私はサイト内のすべての絶対URL(wysiwygコンテンツ、URLフィールド、構成)を見つけて、後で手動管理によって相対URLに変換しようとしています。問題のすべてのURLが同じDrupalサイト内にあります。私はPHPMyAdminを使用して、絶対URL(ノード-/node/NID/edit
、メニュー項目-/admin/structure/menu/item/MLID/edit
など)。しかし、私は段落で苦労しています。
この問題を解決するにはどうすればよいですか?絶対リンクを含む段落のホストノードを見つけるにはどうすればよいですか?
これには、SQLよりもAPIを使用する方が少し簡単かもしれません。私はすべてのノードをロードし、すべてのフィールドをループし、そのように値をチェックしたくなるでしょう。段落フィールドをヒットした場合は、再帰してそのフィールドも確認してください。
これは非常に大まかな例の関数ですが、次のようになります。
function entityHasFieldWithAbsUrl(\Drupal\Core\Entity\ContentEntityInterface $entity, array $types) {
foreach ($entity->getFields() as $key => $field) {
$field_type = $field->getFieldDefinition()->getType();
$field_settings = $field->getSettings();
if ($field_type == 'entity_reference_revisions' && $field_settings['target_type'] == 'paragraph') {
foreach ($field as $item) {
if ($item->entity instanceof \Drupal\paragraphs\ParagraphInterface) {
if (entityHasFieldWithAbsUrl($item->entity, $types)) {
return TRUE;
}
}
}
}
elseif (in_array($field_type, $types)) {
foreach ($field as $item) {
// Change this to something better...
if (strpos($item->value, 'https://www.example.com/') !== FALSE) {
return TRUE;
}
}
}
}
return FALSE;
}
そして、あなたはそれをこのように使うでしょう:
$nodes_with_abs_urls = [];
$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple();
$types = ['text', 'text_long', 'text_with_summary', 'string'];
foreach ($nodes as $node) {
if (entityHasFieldWithAbsUrl($node, $types)) {
$nodes_with_abs_urls[] = $node->id();
}
}
おそらく、インストールに合わせてタイプを微調整する必要がありますが、基本的なレベルで機能するはずです。
つまり、PHPMyAdminでURLを検索し、段落フィールドに属するすべてのテーブル(それらには_paragraph__
_というプレフィックスが付いています)を選択して、それらのすべての_entity_id
_ sを収集していました。次に、一時的なDrushコマンドを使用して、これらの段落をすべてロードし、目的のエンティティタイプ(この場合はノード)に到達するまで、再帰的に$paragraph->getParentEntity()
をロードしました。次に、ノードIDを記録しました。
_function mymodule_drush_command() {
$items = [];
$items['mycommand'] = [
'description' => 'Find the nids of the pids',
'arguments' => [],
'drupal dependencies' => ['mymodule'],
'aliases' => [],
];
return $items;
}
function drush_mymodule_mycommand() {
// Could be improved by retrieving ids via query.
$pids = [/* paragraph entity_ids */];
// For each, recursively search ancestors.
$nids = array_unique(array_filter(array_map(function($pid) {
return _mymodule_find_node(\Drupal\paragraphs\Entity\Paragraph::load($pid));
}, $pids)));
// Print results
drush_print_r(array_map(function($nid) {
return '/node/' . $nid . '/edit';
}, $nids));
}
function _mymodule_find_node($entity){
// Could be improved by handling more than just nodes
if ($entity instanceof \Drupal\node\NodeInterface) return $entity->id();
// If still a paragraph, climb
if ($entity instanceof \Drupal\paragraphs\ParagraphInterface) return _mymodule_find_node($entity->getParentEntity());
// Otherwise, this is an entity we didn't want.
return null;
}
_
この操作の大部分は自動化されている可能性があります。 PHPMyAdminの代わりにクエリを介してエンティティIDを取得し、ブロックや用語などのさまざまなルートタイプを処理するように改善されている可能性があります。すべての段落を読み込まないことで、パフォーマンスが向上する可能性もあります。しかし、上記は現時点で必要なことを行っていたので、そのままにしておきました。