web-dev-qa-db-ja.com

言語ごとにパスエイリアスを削除する

Drupal 8.8.5を実行しています。/admin/config/search/pathを見ると、エイリアスが重複していることがわかります。

残念ながら、当社のWebサイトには6000のURLを持つ多くの重複したエイリアスがあります。/node/1ノードには、en、es、zh-hansの3つの翻訳があります。/node/1にもesの2番目のエントリがあり、削除したい重複パスエイリアスが含まれています。

プログラムでパスのエイリアスを削除する方法を見つける必要があります。パス、エイリアス、言語コードに対して作成、読み取り、更新、削除(CRUD)操作がある場合、重複を排除するソリューションを作成できます。

次のコードは、IDが1のノードに関連付けられたエイリアスデータを取得し、Path、Alias、LangCodeをダンプします。

_$alias = \Drupal::entityTypeManager()->getStorage('path_alias')->load('1');
var_dump($alias->getPath());
var_dump($alias->getAlias());
var_dump($alias->language()->getId());
_

ウェブサイトのベース言語は英語で、最後のvar_dump()enを返します。ここまでは順調ですね。

これら2つの言語のエイリアスデータにアクセスするにはどうすればよいですか?以下の作品を知っています。

_$alias_es = \Drupal::service('path_alias.manager')->getAliasByPath('/node/1','es');
_

目的を達成するために重複するスペイン語パスエイリアスを削除する必要があるので、delete()メソッドを持つエンティティの使用方法を理解する必要があります。次のコードは機能するはずです。

_$alias_es = $alias->getTranslation('es');
_

それは返します:

InvalidArgumentException:無効な翻訳言語が指定されました。

また、要素を1つだけ含む配列を返す$alias->getTranslationLanguages()も試しました(['en'] => object(Drupal\Core\Language\Language))。

元の$alias = \Drupal::entityTypeManager()->getStorage('path_alias')->load('1');には英語の1つの言語の翻訳しかないようです。

esおよびzh-hansのパスエイリアスにアクセスするにはどうすればよいですか?

2
Greg Sims

@berramouありがとうございます!

私の状況で対処する2つのケースがありました:(1)言語の現在のエイリアスと一致しないエイリアス、および(2)現在のエイリアスと一致する同じ言語の重複エイリアス。次のコードは、これらの両方のケースを識別しています。コードは、問題のあるエイリアスオブジェクトを削除しません。コメントされたエイリアスオブジェクトの削除を削除する前に、まずケースを見て、コードが機能するかどうかを確認してください。

$path_alias_manager = \Drupal::entityTypeManager()->getStorage('path_alias');

$nids = \Drupal::entityQuery('node')
  ->execute();

$n = 0;
foreach($nids as $nid) {

  $alias_objects = $path_alias_manager->loadByProperties([
    'path' => "/node/$nid",
  ]);

  foreach(['en','es','zh-hans'] as $lang)
    $current_alias[$lang] = \Drupal::service('path_alias.manager')->getAliasByPath("/node/$nid",$lang);

  $aliases = [];
  foreach($alias_objects as $ao) {
    $lang = $ao->language()->getId();
    $alias = $ao->getAlias();
    $path = $ao->getpath();
    if($current_alias[$lang] != $alias) {
      delete_ao($ao,$alias_objects,$current_alias[$lang],'not current');
    } else {
      if( isset($aliases[$lang]) ) {
        delete_ao($ao,$alias_objects,$current_alias[$lang],'duplicate');
      } else {
        $aliases[$lang] = $alias;
      }
    }
  }
  if($n++ == 100)exit;
}

function delete_ao($ao,$alias_objects,$current,$why) {
  $lang = $ao->language()->getId();
  print_aos($alias_objects);
  print ">> delete as $why: ";
  print_ao($ao);
  if($why == 'not current')
    print ">> current_alias for $lang: $current\n";
  print "\n";
  // $ao->delete();
}

function print_ao($ao) {
  print $ao->getPath() . ', ' .
        $ao->getAlias() . ', ' .
        $ao->language()->getId() . "\n";
}
function print_aos($alias_objects) {
  foreach($alias_objects as $ao)
    print_ao($ao);
}
0
Greg Sims

Esとzh-hansのパスエイリアスにアクセスするにはどうすればよいですか?

インスタンスesなど、言語ごとにすべてのパスエイリアスを取得するには:

$path_alias_manager = \Drupal::entityTypeManager()->getStorage('path_alias');
// Load all path alias for this node for es language.
$alias_objects = $path_alias_manager->loadByProperties([
  'path' => '/node/' . $nid,
  'langcode' => 'en'
]);

重複するスペイン語パスエイリアスを削除する必要があります

$path_alias_manager = \Drupal::entityTypeManager()->getStorage('path_alias');
// Load all path alias for this node for es language.
$alias_objects = $path_alias_manager->loadByProperties([
  'path'     => '/node/' . $nid,
  'langcode' => 'es',
]);

// Get the actual associated spanish path alias to your node.
$spanish_associated_alias = \Drupal::service('path.alias_manager')->getAliasByPath('/node/' . $nid, 'es');
foreach ($alias_objects as $alias_object) {
  // If its not the actual alias delete it.
  if ($alias_object->get('alias')->value !== $spanish_associated_alias ){
    $alias_object->delete();
  }
}
3
berramou