Repo for the search and displace core module including the interface to select files and search and displace operations to run on them.
https://searchanddisplace.com
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
3.8 KiB
138 lines
3.8 KiB
<?php
|
|
|
|
namespace App\SearchDisplace;
|
|
|
|
use App\SearchDisplace\Searchers\Searcher;
|
|
|
|
class SearchAndDisplace
|
|
{
|
|
protected $documentContent;
|
|
protected $info;
|
|
protected $searchOnly;
|
|
protected $isDocument = false;
|
|
|
|
public function __construct($documentContent, $info, $searchOnly, $isDocument = false)
|
|
{
|
|
$this->documentContent = $documentContent;
|
|
$this->info = $info;
|
|
$this->searchOnly = $searchOnly;
|
|
$this->isDocument = $isDocument;
|
|
}
|
|
|
|
/**
|
|
* @return array|mixed
|
|
* @throws \Exception
|
|
*/
|
|
public function execute()
|
|
{
|
|
$searchResult = $this->search();
|
|
|
|
if ($this->searchOnly) {
|
|
return $searchResult;
|
|
}
|
|
|
|
return $this->displace($searchResult);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @return mixed
|
|
* @throws \Exception
|
|
*/
|
|
protected function search()
|
|
{
|
|
$searcher = new Searcher($this->info['searchers'], $this->documentContent);
|
|
|
|
return $searcher->execute();
|
|
}
|
|
|
|
protected function displace($searchResult)
|
|
{
|
|
$replacementIndexes = [];
|
|
$replacements = [];
|
|
|
|
foreach ($this->info['searchers'] as $searcher) {
|
|
$replacements[$searcher['key']] = $searcher;
|
|
}
|
|
|
|
$searchers = [];
|
|
|
|
foreach ($searchResult as $searcher => $searcherResults) {
|
|
$replacementIndexes[$searcher] = [];
|
|
|
|
foreach ($searcherResults as $searcherResult) {
|
|
$searchers[$searcherResult['start']] = array_merge($searcherResult, [
|
|
'searcher' => $searcher
|
|
]);
|
|
}
|
|
}
|
|
|
|
ksort($searchers);
|
|
|
|
$updatedDocumentContent = '';
|
|
$currentIndex = 0;
|
|
|
|
foreach ($searchers as $s => $searcherItem) {
|
|
$partialContent = substr($this->documentContent, $currentIndex, $searcherItem['start'] - $currentIndex);
|
|
|
|
$updatedDocumentContent = $updatedDocumentContent . $partialContent;
|
|
|
|
$start = mb_strlen($updatedDocumentContent);
|
|
|
|
$replacementValue = $replacements[$searcherItem['searcher']]['type'] === 'replace'
|
|
? $replacements[$searcherItem['searcher']]['value']
|
|
: $this->getDisplaceValue($replacements[$searcherItem['searcher']]['value'], $searcherItem['content']);
|
|
|
|
$updatedDocumentContent = $updatedDocumentContent . $replacementValue;
|
|
|
|
$end = mb_strlen($updatedDocumentContent) - 1;
|
|
|
|
if ($start <= $end) {
|
|
$replacementIndexes[$searcherItem['searcher']][] = [
|
|
'start' => $start,
|
|
'end' => $end,
|
|
|
|
'original_start' => $searcherItem['start'],
|
|
'original_end' => $searcherItem['end'],
|
|
];
|
|
}
|
|
|
|
$currentIndex = $searcherItem['end'] + 1;
|
|
}
|
|
|
|
if ($currentIndex < strlen($this->documentContent) - 1) {
|
|
$updatedDocumentContent = $updatedDocumentContent . substr($this->documentContent, $currentIndex);
|
|
}
|
|
|
|
if($this->isDocument) {
|
|
$needReplace = $this->needReplaceInDocument($replacementIndexes);
|
|
|
|
if(!$needReplace) return false;
|
|
}
|
|
|
|
return [
|
|
'content' => $updatedDocumentContent,
|
|
'indexes' => $replacementIndexes,
|
|
];
|
|
}
|
|
|
|
protected function getDisplaceValue($displaceValue, $content)
|
|
{
|
|
// return "<$displaceValue>$content</$displaceValue>";
|
|
return "{{$displaceValue}}{$content}{/{$displaceValue}}";
|
|
}
|
|
|
|
protected function needReplaceInDocument($replacementIndexes)
|
|
{
|
|
$needReplace = false;
|
|
|
|
foreach($replacementIndexes as $replacement) {
|
|
if(count($replacement) > 0 ) {
|
|
$needReplace = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $needReplace;
|
|
}
|
|
}
|