View source
<?php
namespace Drupal\scanner\Plugin\Scanner;
use Drupal\Core\StringTranslation\StringTranslationTrait;
class Paragraph extends Entity {
use StringTranslationTrait;
public function search($field, array $values) {
$title_collect = [];
list($bundle, $fieldname) = explode(':', $field);
$query = \Drupal::entityQuery('paragraph');
$query
->condition('type', $bundle);
if ($values['published']) {
$query
->condition('status', 1);
}
$conditionVals = parent::buildCondition($values['search'], $values['mode'], $values['wholeword'], $values['regex'], $values['preceded'], $values['followed']);
if ($values['language'] !== 'all') {
$query
->condition('langcode', $values['language'], '=');
$query
->condition($fieldname, $conditionVals['condition'], $conditionVals['operator'], $values['language']);
}
else {
$query
->condition($fieldname, $conditionVals['condition'], $conditionVals['operator']);
}
$entities = $query
->execute();
if (!empty($entities)) {
$paragraphs = \Drupal::entityTypeManager()
->getStorage('paragraph')
->loadMultiple($entities);
foreach ($paragraphs as $paragraph) {
if (!empty($paragraph)) {
$parentEntity = $paragraph
->getParentEntity();
if (!empty($parentEntity)) {
$parentEntityType = $parentEntity
->getEntityTypeId();
if ($parentEntityType != 'node') {
if ($parentEntity
->getParentEntity()
->getEntityTypeId() == 'node') {
$parentEntity = $parentEntity
->getParentEntity();
}
else {
while ($parentEntity
->getParentEntity()
->getEntityTypeId() != 'node') {
$parentEntity = $parentEntity
->getParentEntity();
}
}
}
$id = $parentEntity
->id();
$paraField = $paragraph
->get($fieldname);
$fieldType = $paraField
->getFieldDefinition()
->getType();
if (in_array($fieldType, [
'text_with_summary',
'text',
'text_long',
])) {
$fieldValue = $paraField
->getValue()[0];
$title_collect[$id]['title'] = $parentEntity
->getTitle();
preg_match_all($conditionVals['phpRegex'], $fieldValue['value'], $matches, PREG_OFFSET_CAPTURE);
$newValues = [];
foreach ($matches[0] as $v) {
$start = $v[1];
if ($values['preceded'] !== '') {
$start -= strlen($values['preceded']);
}
$replaced = preg_replace($conditionVals['phpRegex'], "<strong>{$v[0]}</strong>", preg_split("/\\s+/", substr($fieldValue['value'], $start), 6));
if (count($replaced) > 1) {
array_pop($replaced);
}
$newValues[] = implode(' ', $replaced);
}
$title_collect[$id]['field'] = $newValues;
}
elseif ($fieldType == 'string') {
$title_collect[$id]['title'] = $parentEntity
->getTitle();
preg_match($conditionVals['phpRegex'], $paraField
->getString(), $matches, PREG_OFFSET_CAPTURE);
$match = $matches[0][0];
$replaced = preg_replace($conditionVals['phpRegex'], "<strong>{$match}</strong>", $paraField
->getString());
$title_collect[$id]['field'] = [
$replaced,
];
}
}
}
}
}
return $title_collect;
}
public function replace($field, array $values, array $undo_data) {
list($entityType, $bundle, $fieldname) = explode(':', $field);
$data = $undo_data;
$query = \Drupal::entityQuery($entityType);
$query
->condition('type', $bundle);
if ($values['published']) {
$query
->condition('status', 1);
}
$conditionVals = parent::buildCondition($values['search'], $values['mode'], $values['wholeword'], $values['regex'], $values['preceded'], $values['followed']);
if ($values['language'] !== 'all') {
$query
->condition($fieldname, $conditionVals['condition'], $conditionVals['operator'], $values['language']);
}
else {
$query
->condition($fieldname, $conditionVals['condition'], $conditionVals['operator']);
}
$entities = $query
->execute();
$paragraphs = \Drupal::entityTypeManager()
->getStorage('paragraph')
->loadMultiple($entities);
foreach ($paragraphs as $pid => $paragraph) {
$paraField = $paragraph
->get($fieldname);
$fieldType = $paraField
->getFieldDefinition()
->getType();
if (in_array($fieldType, [
'text_with_summary',
'text',
'text_long',
])) {
$fieldValue = $paraField
->getValue()[0];
$fieldValue['value'] = preg_replace($conditionVals['phpRegex'], $values['replace'], $fieldValue['value']);
$paragraph->{$fieldname} = $fieldValue;
if (!isset($data["paragraph:{$pid}"]['new_vid'])) {
$data["paragraph:{$pid}"]['old_vid'] = $paragraph
->getRevisionId();
$paragraph
->setNewRevision(TRUE);
}
$paragraph
->save();
$data["paragraph:{$pid}"]['new_vid'] = $paragraph
->getRevisionId();
$processed = $this
->handleParentRelationship($paragraph, $values, $data);
if ($processed == FALSE) {
continue;
}
}
elseif ($fieldType == 'string') {
$fieldValue = preg_replace($conditionVals['phpRegex'], $values['replace'], $paraField
->getString());
$paragraph->{$fieldname} = $fieldValue;
if (!isset($data["paragraph:{$pid}"]['new_vid'])) {
$data["paragraph:{$pid}"]['old_vid'] = $paragraph
->getRevisionId();
$paragraph
->setNewRevision(TRUE);
}
$paragraph
->save();
$data["paragraph:{$pid}"]['new_vid'] = $paragraph
->getRevisionId();
$processed = $this
->handleParentRelationship($paragraph, $values, $data);
if ($processed == FALSE) {
continue;
}
}
}
return $data;
}
public function undo(array $data) {
$paraRevision = \Drupal::entityTypeManager()
->getStorage('paragraph')
->loadRevision($data['old_vid']);
$paraRevision
->setNewRevision(TRUE);
$paraRevision
->isDefaultRevision(TRUE);
$paraRevision
->save();
}
protected function handleParentRelationship($paragraph, array $values, array &$data) {
$pid = $paragraph
->id();
$parentEntity = $paragraph
->getParentEntity();
if (empty($parentEntity)) {
return FALSE;
}
$id = $parentEntity
->id();
$parentEntityType = $parentEntity
->getEntityTypeId();
$isProcessed = FALSE;
if ($parentEntityType == 'node') {
$parentField = $paragraph
->get('parent_field_name')
->getString();
$index = $this
->getMultiValueIndex($parentEntity->{$parentField}
->getValue(), $pid);
if ($index < 0) {
\Drupal::logger('scanner')
->notice('Unable to find the delta for this paragraph in the parent entity\'s field (id: @id).', [
'@id' => $pid,
]);
return $isProcessed;
}
if (!isset($data["node:{$id}"]['new_vid'])) {
$data["node:{$id}"]['old_vid'] = $parentEntity
->getRevisionId();
$parentEntity
->setNewRevision(TRUE);
$parentEntity->revision_log = $this
->t('Replaced @search with @replace via Scanner Search and Replace module.', [
'@search' => $values['search'],
'@replace' => $values['replace'],
]);
}
$parentEntity->{$parentField}
->set($index, [
'target_id' => $pid,
'target_revision_id' => $paragraph
->getRevisionId(),
]);
$parentEntity
->save();
$data["node:{$id}"]['new_vid'] = $parentEntity
->getRevisionId();
$isProcessed = TRUE;
return $isProcessed;
}
elseif ($parentEntityType == 'paragraph') {
$grandParentEntity = $parentEntity
->getParentEntity();
if ($grandParentEntity
->getEntityTypeId() != 'node') {
return $isProcessed;
}
$parentField = $paragraph
->get('parent_field_name')
->getString();
$index = $this
->getMultiValueIndex($parentEntity->{$parentField}
->getValue(), $pid);
if ($index < 0) {
\Drupal::logger('scanner')
->notice('Unable to find the delta for this paragraph in the parent entity\'s field (id: @id).', [
'@id' => $pid,
]);
return $isProcessed;
}
if (!isset($data["paragraph:{$id}"]['new_vid'])) {
$data["paragraph:{$id}"]['old_vid'] = $parentEntity
->getRevisionId();
$parentEntity
->setNewRevision(TRUE);
}
$parentEntity->{$parentField}
->set($index, [
'target_id' => $paragraph
->id(),
'target_revision_id' => $paragraph
->getRevisionId(),
]);
$parentEntity
->save();
$data["paragraph:{$id}"]['new_vid'] = $parentEntity
->getRevisionId();
$grandParentId = $grandParentEntity
->id();
$grandParentField = $parentEntity
->get('parent_field_name')
->getString();
$index = $this
->getMultiValueIndex($grandParentEntity->{$grandParentField}
->getValue(), $id);
if ($index < 0) {
\Drupal::logger('scanner')
->notice('Unable to find the delta for this paragraph in the parent entity\'s field (id: @id).', [
'@id' => $id,
]);
return $isProcessed;
}
if (!isset($data["node:{$grandParentId}"]['new_vid'])) {
$data["node:{$grandParentId}"]['old_vid'] = $grandParentEntity
->getRevisionId();
$grandParentEntity
->setNewRevision(TRUE);
$grandParentEntity->revision_log = $this
->t('Replaced @search with @replace via Scanner Search and Replace module.', [
'@search' => $values['search'],
'@replace' => $values['replace'],
]);
}
$grandParentEntity->{$grandParentField}
->set($index, [
'target_id' => $parentEntity
->id(),
'target_revision_id' => $parentEntity
->getRevisionId(),
]);
$grandParentEntity
->save();
$data["node:{$grandParentId}"]['new_vid'] = $grandParentEntity
->getRevisionId();
$isProcessed = TRUE;
return $isProcessed;
}
else {
return $isProcessed;
}
}
protected function getMultiValueIndex($values, $pid) {
foreach ($values as $key => $value) {
if ($value['target_id'] == $pid) {
return $key;
}
}
return -1;
}
}