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.

109 lines
3.0 KiB

3 years ago
  1. <?php
  2. namespace App\SearchDisplace;
  3. use App\SearchDisplace\Searchers\Searcher;
  4. class SearchAndDisplace
  5. {
  6. protected $documentContent;
  7. protected $info;
  8. protected $searchOnly = false;
  9. public function __construct($documentContent, $info, $searchOnly = false)
  10. {
  11. $this->documentContent = $documentContent;
  12. $this->info = $info;
  13. $this->searchOnly = $searchOnly;
  14. }
  15. public function execute()
  16. {
  17. $searchResult = $this->search();
  18. if ($this->searchOnly) {
  19. return $searchResult;
  20. }
  21. return $this->displace($searchResult);
  22. }
  23. /**
  24. *
  25. * @return mixed
  26. * @throws \Exception
  27. */
  28. protected function search()
  29. {
  30. $searcher = new Searcher($this->info['searchers'], $this->documentContent);
  31. return $searcher->execute();
  32. }
  33. protected function displace($searchResult)
  34. {
  35. $replacementIndexes = [];
  36. $replacements = [];
  37. foreach ($this->info['searchers'] as $searcher) {
  38. $replacements[$searcher['key']] = $searcher;
  39. }
  40. $searchers = [];
  41. foreach ($searchResult as $searcher => $searcherResults) {
  42. $replacementIndexes[$searcher] = [];
  43. foreach ($searcherResults as $searcherResult) {
  44. $searchers[$searcherResult['start']] = array_merge($searcherResult, [
  45. 'searcher' => $searcher
  46. ]);
  47. }
  48. }
  49. ksort($searchers);
  50. $updatedDocumentContent = '';
  51. $currentIndex = 0;
  52. foreach ($searchers as $s => $searcherItem) {
  53. $partialContent = substr($this->documentContent, $currentIndex, $searcherItem['start'] - $currentIndex);
  54. $updatedDocumentContent = $updatedDocumentContent . $partialContent;
  55. $start = mb_strlen($updatedDocumentContent);
  56. $replacementValue = $replacements[$searcherItem['searcher']]['type'] === 'replace'
  57. ? $replacements[$searcherItem['searcher']]['value']
  58. : $this->getDisplaceValue($replacements[$searcherItem['searcher']]['value'], $searcherItem['content']);
  59. $updatedDocumentContent = $updatedDocumentContent . $replacementValue;
  60. $end = mb_strlen($updatedDocumentContent) - 1;
  61. if ($start <= $end) {
  62. $replacementIndexes[$searcherItem['searcher']][] = [
  63. 'start' => $start,
  64. 'end' => $end,
  65. ];
  66. }
  67. $currentIndex = $searcherItem['end'] + 1;
  68. }
  69. if ($currentIndex < strlen($this->documentContent) - 1) {
  70. $updatedDocumentContent = $updatedDocumentContent . substr($this->documentContent, $currentIndex);
  71. }
  72. return [
  73. 'content' => $updatedDocumentContent,
  74. 'indexes' => $replacementIndexes,
  75. ];
  76. }
  77. protected function getDisplaceValue($displaceValue, $content)
  78. {
  79. // return "<$displaceValue>$content</$displaceValue>";
  80. return "{{$displaceValue}}{$content}{/{$displaceValue}}";
  81. }
  82. }