Skip to content

Commit

Permalink
Merge branch 'develop' into DP-28815_new_org_nav
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurbaghdas authored Sep 6, 2023
2 parents 12bf643 + 4382a55 commit 0adf6d0
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 242 deletions.
41 changes: 41 additions & 0 deletions changelogs/DP-288257.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#
# Write your changelog entry here. Every pull request must have a changelog yml file.
#
# Change types:
# #############################################################################
# You can use one of the following types:
# - Added: For new features.
# - Changed: For changes to existing functionality.
# - Deprecated: For soon-to-be removed features.
# - Removed: For removed features.
# - Fixed: For any bug fixes.
# - Security: In case of vulnerabilities.
#
# Format
# #############################################################################
# The format is crucial. Please follow the examples below. For reference, the requirements are:
# - All 3 parts are required and you must include "Type", "description" and "issue".
# - "Type" must be left aligned and followed by a colon.
# - "description" must be indented with 2 spaces followed by a colon
# - "issue" must be indented with 4 spaces followed by a colon.
# - "issue" is for the Jira ticket number only e.g. DP-1234
# - No extra spaces, indents, or blank lines are allowed.
#
# Example:
# #############################################################################
# Fixed:
# - description: Fixes scrolling on edit pages in Safari.
# issue: DP-13314
#
# You may add more than 1 description & issue for each type using the following format:
# Changed:
# - description: Automating the release branch.
# issue: DP-10166
# - description: Second change item that needs a description.
# issue: DP-19875
# - description: Third change item that needs a description along with an issue.
# issue: DP-19843
#
Changed:
- description: Consolidate two Drush commands into one - ma:heal-references-to-trash
issue: DP-288257
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,41 @@
namespace Drupal\mass_redirects\Commands;

use Consolidation\OutputFormatters\StructuredData\RowsOfFields;
use Drupal\Component\Utility\Html;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityPublishedInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\Url;
use Drupal\Driver\Exception\Exception;
use Drupal\mass_content\Field\FieldType\DynamicLinkItem;
use Drupal\mass_redirects\Form\MoveRedirectsForm;
use Drupal\mayflower\Helper;
use Drupal\redirect\RedirectRepository;
use Drupal\text\Plugin\Field\FieldType\TextLongItem;
use Drupal\text\Plugin\Field\FieldType\TextWithSummaryItem;
use Drush\Commands\DrushCommands;
use Drush\Drush;

class MassRedirectsCommands extends DrushCommands {

/**
* EntityCommands constructor.
*/
public function __construct(
protected EntityTypeManagerInterface $entityTypeManager,
protected Connection $connection,
protected RedirectRepository $redirectRepository
) {
parent::__construct();
}

/**
* Re-point entity usages that point via a redirect.
*
* @command ma:heal
* Use --simulate to get a report, and skip healing.
*
* @command ma:heal-references-to-trash
* @field-labels
* success: Success
* parent_id: Parent id
* parent_type: Parent type
* parent_bundle: Parent Bundle
Expand All @@ -41,11 +50,11 @@ public function __construct(
* from_type: From type
* to_id: To Id
* to_type: To Type
* @default-fields parent_id,parent_type,parent_bundle,parent_published,usage_id,usage_type,field,method,from_id,from_type,to_id,to_type
* @default-fields success,parent_id,parent_type,parent_bundle,parent_published,usage_id,usage_type,field,method,from_id,from_type,to_id,to_type
* @aliases mah
* @filter-default-field from_id
*/
public function heal($options = ['format' => 'table']): RowsOfFields {
public function healReferences($options = ['format' => 'table']): RowsOfFields {
$rows = [];

// Get all usages that point to a trashed node.
Expand Down Expand Up @@ -118,6 +127,7 @@ public function heal($options = ['format' => 'table']): RowsOfFields {
}

$result = [
'success' => 'No',
'parent_id' => $parent->id(),
'parent_type' => $parent->getEntityTypeId(),
'parent_bundle' => $parent->bundle(),
Expand All @@ -131,16 +141,142 @@ public function heal($options = ['format' => 'table']): RowsOfFields {
'to_id' => $parameters['node'],
'to_type' => 'node',
];
// We can re-point this usage.
if (!Drush::simulate()) {
// Re-point this usage.
if ($this->heal($usage, $result)) {
$result['success'] = 'Yes';
}
}
$rows[] = $result;
\Drupal::queue('mass_redirects_repoint')->createItem($result);
}
}

}
return new RowsOfFields($rows);
}

public function heal(ContentEntityInterface $entity, array $data): bool {
$changed = $saved = FALSE;
$options = ['absolute' => TRUE];

$field_name = $data['field'];
$list = $entity->get($field_name);
$uri_old = 'entity:' . $data['from_type'] . '/' . $data['from_id'];
$uri_new = 'entity:' . $data['from_type'] . '/' . $data['to_id'];
foreach ($list as $delta => $item) {
switch (get_class($item)) {
case DynamicLinkItem::class:
$values[$delta] = $item->getValue();
$item_uri = $item->get('uri')->getString();
$item_uri_path = parse_url($item_uri, PHP_URL_PATH);
if ($item_uri == $uri_old) {
$values[$delta]['uri'] = $uri_new;
$changed = TRUE;
}
elseif ($item_uri_path == Url::fromUri($uri_old)->toString()) {
$values[$delta]['uri'] = Url::fromUri($uri_new, $options)->toString();
$changed = TRUE;
}
break;

case EntityReferenceItem::class:
$values[$delta] = $item->getValue();
if ($item->get('target_id')->getString() == $data['from_id']) {
$values[$delta]['target_id'] = $data['to_id'];
$changed = TRUE;
}
break;

case TextLongItem::class:
case TextWithSummaryItem::class:
$values[$delta] = $item->getValue();
$value = $item->getValue()['value'];
// First check for the entity ID
if (str_contains($value, $data['from_id'])) {
$replaced = str_replace($data['from_id'], $data['to_id'], $value);
$value = $replaced;
$values[$delta]['value'] = $replaced;
$changed = TRUE;
}
// Next check for the link. We want relative links not
// absolute so domain mismatch isn't an issue.
if (str_contains($value, Url::fromUri($uri_old)->toString())) {
$replaced = str_replace(Url::fromUri($uri_old)->toString(), Url::fromUri($uri_new)->toString(), $value);
$value = $replaced;
$values[$delta]['value'] = $replaced;
$changed = TRUE;
}

// Check for the linkit values.
if (str_contains($value, 'data-entity-uuid')) {

$storage_old = $this->entityTypeManager->getStorage($data['from_type']);

if ($storage_old) {
$entity_old = $storage_old->load($data['from_id']);
if ($entity_old) {
if (str_contains($value, $entity_old->uuid())) {
$dom = Html::load($value);
$xpath = new \DOMXPath($dom);
foreach ($xpath->query('//a[@data-entity-type and @data-entity-uuid]') as $element) {
if ($element->getAttribute('data-entity-uuid') == $entity_old->uuid()) {
// Parse link href as url,
// extract query and fragment from it.
$href_url = parse_url($element->getAttribute('href'));
$anchor = empty($href_url["fragment"]) ? '' : '#' . $href_url["fragment"];
$query = empty($href_url["query"]) ? '' : '?' . $href_url["query"];

$storage_new = $this->entityTypeManager->getStorage($data['to_type']);
if ($storage_new) {
$entity_new = $storage_new->load($data['to_id']);
if ($entity_new) {
$substitution = \Drupal::service('plugin.manager.linkit.substitution');
$url = $substitution
->createInstance('canonical')
->getUrl($entity_new);
$element->setAttribute('data-entity-uuid', $entity_new->uuid());
$element->setAttribute('href', $url->getGeneratedUrl() . $query . $anchor);
$changed = TRUE;
}
}
}
}
if ($changed) {
$replaced = Html::serialize($dom);
$value = $replaced;
$values[$delta]['value'] = $replaced;
}
}
}
}
}

// Check if there are manually entered html links.
$old_url = str_replace('---unpublished', '', Url::fromUri($uri_old)->toString());
if (str_contains($value, $old_url)) {
$replaced = str_replace($old_url, Url::fromUri($uri_new)->toString(), $value);
$values[$delta]['value'] = $replaced;
$changed = TRUE;
}
break;
}

// Update the field values if any changes were made.
if ($changed) {
if (method_exists($entity, 'setRevisionLogMessage')) {
$entity->setNewRevision();
$entity->setRevisionLogMessage('Revision created to fix redirects.');
$entity->setRevisionCreationTime(\Drupal::time()->getRequestTime());
}
$entity->set($field_name, $values);
$entity->save();
$saved = TRUE;
}

}
return $saved;
}

/**
* An example of the table output format.
*
Expand Down
Loading

0 comments on commit 0adf6d0

Please sign in to comment.