diff --git a/app/Http/Controllers/FileController.php b/app/Http/Controllers/FileController.php
index 49f16f3..025e7cb 100644
--- a/app/Http/Controllers/FileController.php
+++ b/app/Http/Controllers/FileController.php
@@ -7,14 +7,13 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\UploadedFile;
use GuzzleHttp\Exception\BadResponseException;
-use App\SearchDisplace\SearchAndDisplaceXML;
-use Symfony\Component\Process\Process;
+use App\SearchDisplace\Convertor\Convertor;
class FileController extends Controller
{
public function __construct()
{
- $this->directoryPath = storage_path("app/contracts/");
+ $this->storage = Storage::disk('local');
}
/**
@@ -46,14 +45,13 @@ class FileController extends Controller
'name' => $file->getClientOriginalName()
]);
- $originalFile = $fileId . "/{$fileId}." . $file->extension();
+ $originalFile = $fileId . "/document." . $file->extension();
- Storage::disk('local')->put("contracts/{$originalFile}", file_get_contents($file)); // keep the original file
+ $this->storage->put("contracts/{$originalFile}", file_get_contents($file)); // keep the original file
- $process = new Process(['soffice', '--convert-to', 'xml', $this->directoryPath . $originalFile, '--outdir', $this->directoryPath . $fileId]);
- $process->run();
+ $xml = Convertor::convert('xml', $this->storage->path("contracts/" . $originalFile));
- Storage::delete("contracts/{$originalFile}");
+ $this->storage->delete("contracts/{$originalFile}");
return response()->json([
'id' => $fileId,
@@ -77,14 +75,12 @@ class FileController extends Controller
public function convert(): JsonResponse
{
$file = (object) request()->input('file');
- $searchers = request()->input('searchers');
+ $xml = $this->storage->path("contracts/{$file->id}/document_sdapplied.xml");
- $xml = $this->directoryPath . "{$file->id}/{$file->id}.xml";
-
- (new SearchAndDisplaceXML($xml, $searchers, $file->type))->execute();
+ $original = Convertor::convert($file->type, $xml, true);
return response()->json([
- 'path' => "tmp/{$file->id}.{$file->type}"
+ 'path' => "tmp/$original"
]);
}
@@ -95,21 +91,20 @@ class FileController extends Controller
*/
public function download(string $path)
{
- return Storage::download($path);
+ return $this->storage->download($path);
}
/**
- * Delete a file currently in progress
+ * Clear contracts and tmp directory
*
* @param string $id
* @return JsonResponse
*/
public function delete(string $id): JsonResponse
{
- Storage::deleteDirectory("contracts/${id}");
-
- $tmpFiles = Storage::allFiles("tmp");
- $success = Storage::delete($tmpFiles);
+ $this->storage->deleteDirectory("contracts/${id}");
+ $tmpFiles = $this->storage->allFiles("tmp");
+ $success = $this->storage->delete($tmpFiles);
return response()->json(['success' => $success]);
}
diff --git a/app/Http/Controllers/SearchAndDisplaceController.php b/app/Http/Controllers/SearchAndDisplaceController.php
index c360a99..03f0072 100644
--- a/app/Http/Controllers/SearchAndDisplaceController.php
+++ b/app/Http/Controllers/SearchAndDisplaceController.php
@@ -3,10 +3,18 @@
namespace App\Http\Controllers;
use App\SearchDisplace\Documents\DocumentFile;
-use App\SearchDisplace\SearchAndDisplaceJSON;
+use Illuminate\Support\Facades\Storage;
+use App\SearchDisplace\SearchAndDisplaceXML;
class SearchAndDisplaceController extends Controller
{
+ protected $storage;
+
+ public function __construct()
+ {
+ $this->storage = Storage::disk('local');
+ }
+
public function show($id)
{
$handler = new DocumentFile();
@@ -14,9 +22,10 @@ class SearchAndDisplaceController extends Controller
try {
$result = $handler->getAfterIngest($id);
- // if ($result['status'] !== 'processing') {
- // $handler->destroy($id);
- // }
+ // remove HTML file after receiving it's content
+ if ($result['status'] !== 'processing') {
+ $this->storage->delete("contracts/$id/document.html");
+ }
return response()->json($result, 200);
} catch (\Exception $exception) {
@@ -29,7 +38,7 @@ class SearchAndDisplaceController extends Controller
public function store()
{
request()->validate([
- 'file' => 'required', // String or file.
+ 'file' => 'required', // file.
'searchers' => 'required|array',
'searchers.*.key' => 'required',
'searchers.*.type' => 'required|in:replace,displace',
@@ -37,16 +46,23 @@ class SearchAndDisplaceController extends Controller
'searchOnly' => 'nullable|boolean'
]);
+ $file = request()->input('file');
$searchOnly = request()->input('searchOnly') ?? false;
- $searchAndDisplace = new SearchAndDisplaceJSON(
- request()->input('file'),
- request()->input('searchers'),
- $searchOnly
- );
+ $changes = (new SearchAndDisplaceXML($file, request()->input('searchers'), $searchOnly))->execute();
try {
- return response()->json($searchAndDisplace->execute(), 200);
+ $processedFile = "contracts/$file/document_sdapplied.html";
+
+ if($this->storage->exists($processedFile)) {
+ $processedFileContent = $this->storage->get($processedFile);
+ $this->storage->delete($processedFile);
+
+ return response()->json([
+ 'content' => $processedFileContent,
+ 'indexes' => []
+ ], 200);
+ }
} catch (\Exception $exception) {
return response()->json([
'message' => $exception->getMessage(),
diff --git a/app/SearchDisplace/Convertor/Convertor.php b/app/SearchDisplace/Convertor/Convertor.php
new file mode 100644
index 0000000..c18a460
--- /dev/null
+++ b/app/SearchDisplace/Convertor/Convertor.php
@@ -0,0 +1,35 @@
+run();
+
+ return $path['filename'] . '.' . $to;
+ }
+}
\ No newline at end of file
diff --git a/app/SearchDisplace/Documents/DocumentFile.php b/app/SearchDisplace/Documents/DocumentFile.php
index 37b878d..d5c329b 100644
--- a/app/SearchDisplace/Documents/DocumentFile.php
+++ b/app/SearchDisplace/Documents/DocumentFile.php
@@ -3,6 +3,7 @@
namespace App\SearchDisplace\Documents;
use Illuminate\Support\Facades\Storage;
+use DOMDocument;
class DocumentFile
{
@@ -18,10 +19,10 @@ class DocumentFile
$path = $this->getPath($id);
// Ingest success.
- if ($this->storage->exists("$path/document.json")) {
+ if ($this->storage->exists("$path/document.html")) {
return [
'status' => 'success',
- 'content' => $this->getDocumentContent($path),
+ 'content' => $this->getDocumentContent($path, $id),
];
}
@@ -50,29 +51,27 @@ class DocumentFile
return "contracts/$id";
}
- protected function getDocumentContent($path)
+ protected function getDocumentContent($path, $id)
{
- $content = json_decode($this->storage->get("$path/document.json"));
+ $document = $this->storage->path($path) . '/document.html';
- return $this->convertToHTML($content);
+ $this->updateImagesPath($document, $id);
+
+ return file_get_contents($document);
}
- protected function convertToHTML($elements)
+ public static function updateImagesPath($document, $id)
{
- $html = '';
- $url = url('/') . '/contracts-images';
- foreach($elements as $key => $element) {
- if($element->tag !== 'img') {
- $html .= "<$element->tag style=\"$element->style\">$element->content$element->tag>";
- } else {
- $src = $url . '/' . str_replace(' ', '%20', $element->src);
- $html .= "style src=\"$src\" alt=\"$element->details\">";
- }
-
- if($key !== array_key_last($elements))
- $html .= '
';
+ $html = new DOMDocument();
+ $html->loadHTMLFile($document);
+ $url = url('/') . "/contracts-images/$id/";
+
+ foreach($html->getElementsByTagName('img') as $image) {
+ $src = $image->getAttribute('src');
+
+ $image->setAttribute('src', $url . $src);
}
- return $html;
+ $html->saveHTMLFile($document);
}
}
diff --git a/app/SearchDisplace/Ingest/HandleReceivedDocument.php b/app/SearchDisplace/Ingest/HandleReceivedDocument.php
index d25792a..fe92cea 100644
--- a/app/SearchDisplace/Ingest/HandleReceivedDocument.php
+++ b/app/SearchDisplace/Ingest/HandleReceivedDocument.php
@@ -35,7 +35,7 @@ class HandleReceivedDocument
*/
public function handle()
{
- if ($this->fileResultType === 'json') {
+ if ($this->fileResultType === 'html') {
$this->handleDocument();
return;
@@ -58,7 +58,7 @@ class HandleReceivedDocument
// The .md extension signals the success status, the lack of signals the fail status.
if ($this->status === 'success') {
- $fileName = $fileName . '.json';
+ $fileName = $fileName . '.html';
}
$dir = "contracts/$this->id";
diff --git a/app/SearchDisplace/Ingest/SendDocument.php b/app/SearchDisplace/Ingest/SendDocument.php
index e9935e9..ec39e12 100644
--- a/app/SearchDisplace/Ingest/SendDocument.php
+++ b/app/SearchDisplace/Ingest/SendDocument.php
@@ -23,10 +23,10 @@ class SendDocument
* @param string $fileResultType
* @throws \Exception
*/
- public function execute($id, $document, string $fileResultType = 'json')
+ public function execute($id, $document, string $fileResultType = 'html')
{
try {
- if ( ! in_array($fileResultType, ['md', 'original', 'json'])) {
+ if ($fileResultType !== 'html') {
throw new \Exception('Invalid file result type provided.');
}
diff --git a/app/SearchDisplace/SearchAndDisplace.php b/app/SearchDisplace/SearchAndDisplace.php
index de34f2f..7914baa 100644
--- a/app/SearchDisplace/SearchAndDisplace.php
+++ b/app/SearchDisplace/SearchAndDisplace.php
@@ -8,10 +8,10 @@ class SearchAndDisplace
{
protected $documentContent;
protected $info;
- protected $searchOnly = false;
+ protected $searchOnly;
protected $isDocument = false;
- public function __construct($documentContent, $info, $searchOnly = false, $isDocument = false)
+ public function __construct($documentContent, $info, $searchOnly, $isDocument = false)
{
$this->documentContent = $documentContent;
$this->info = $info;
diff --git a/app/SearchDisplace/SearchAndDisplaceJSON.php b/app/SearchDisplace/SearchAndDisplaceJSON.php
deleted file mode 100644
index 9f1a3e3..0000000
--- a/app/SearchDisplace/SearchAndDisplaceJSON.php
+++ /dev/null
@@ -1,98 +0,0 @@
-content = $file : $this->file = $file . '/document.json';
- $this->searchers = $searchers;
-
- $this->storage = Storage::disk('local');
- }
-
- public function execute()
- {
- if(isset($this->content)) {
- $search = new SearchAndDisplace(
- stripslashes($this->content),
- [
- 'searchers' => $this->searchers,
- ],
- true
- );
-
- return $search->execute();
- }
-
- if(! $this->storage->exists("contracts/$this->file")) {
- return;
- }
-
- try {
- $content = $this->getContent();
- } catch (\Exception $exception) {
- \Illuminate\Support\Facades\Log::info('EXCEPTION: ' . $exception->getMessage());
-
- return;
- }
-
- $searchDisplace = $this->applySD($content);
-
- $convert = new HtmlOutput($searchDisplace);
-
- return $convert->getData();
- }
-
- protected function getContent()
- {
- return json_decode($this->storage->get("contracts/$this->file"));
- }
-
- protected function applySD($elements)
- {
- $indexes = [];
-
- foreach($elements as $element) {
- if($element->tag === 'img')
- continue;
-
- $search = new SearchAndDisplace(
- stripslashes($element->content),
- [
- 'searchers' => $this->searchers,
- ],
- false,
- true
- );
-
- $changed = $search->execute();
-
- if($changed) {
- foreach($changed['indexes'] as $key => $searcher) {
- foreach($searcher as $change) {
- if($change['start']) {
- $indexes[$key][] = $change;
- $element->paragraph = $key;
- }
- }
- }
- $element->content = $changed['content'];
- }
- }
-
- return [
- 'content' => $elements,
- 'indexes' => $indexes
- ];
- }
-}
\ No newline at end of file
diff --git a/app/SearchDisplace/SearchAndDisplaceXML.php b/app/SearchDisplace/SearchAndDisplaceXML.php
index 02725fb..c4d4583 100644
--- a/app/SearchDisplace/SearchAndDisplaceXML.php
+++ b/app/SearchDisplace/SearchAndDisplaceXML.php
@@ -2,57 +2,132 @@
namespace App\SearchDisplace;
-use Symfony\Component\Process\Process;
+use App\SearchDisplace\Documents\DocumentFile;
+use Illuminate\Support\Facades\Storage;
+use App\SearchDisplace\Convertor\Convertor;
class SearchAndDisplaceXML
{
protected $file;
protected $searchers;
- protected $type;
+ protected $storage;
+ protected $searchOnly;
- public function __construct($file, $searchers, $type = 'odt')
+ public function __construct($file, $searchers, $searchOnly)
{
- $this->file = $file;
+ $this->fileDirectory = $file;
$this->searchers = $searchers;
- $this->type = $type;
+ $this->storage = Storage::disk('local');
+ $this->searchOnly = $searchOnly;
}
public function execute()
{
- $this->applySD();
+ $sdXML = $this->applySD();
+ $pathinfo = pathinfo($sdXML);
- $this->convertToOriginalFileType();
+ $this->convertSearchDisplacedXMLToHTML($sdXML);
+
+ DocumentFile::updateImagesPath($pathinfo['dirname'] . '/document_sdapplied.html', $this->fileDirectory);
+
+ return $pathinfo['filename'];
}
- protected function convertToOriginalFileType()
+ /**
+ * Convert (Search displaced) XML to HTML for browser preview
+ *
+ * @return void
+ */
+ protected function convertSearchDisplacedXMLToHTML($file)
{
- (new Process(['soffice', '--convert-to', $this->type, $this->file, '--outdir', storage_path('app/tmp/')]))->run();
+ Convertor::convert('html', $file);
}
+ /**
+ * Read XML document and send text contents to SD
+ *
+ * @return void
+ */
protected function applySD()
{
$dom = new \DOMDocument();
- $dom->load($this->file);
-
- foreach($dom->getElementsByTagName('span') as $p) {
- $search = new SearchAndDisplace(
- stripslashes($p->textContent),
- [
- 'searchers' => $this->searchers,
- ],
- false,
- true
- );
-
- $changed = $search->execute();
+ $filePath = $this->storage->path("contracts/$this->fileDirectory");
+ $dom->load($filePath . "/document.xml");
- if(!$changed) {
- continue;
- }
+ foreach($dom->getElementsByTagName('p') as $p) {
+ if(count($p->childNodes) > 0 && isset($p->parentNode->tagName) && $p->parentNode->tagName !== "table:table-cell") {
+ foreach($p->childNodes as $child) {
+ if(isset($child->tagName) && $child->tagName === "text:span") {
+ $content = trim($child->textContent);
+ if($content == '') {
+ continue;
+ }
- $p->textContent = $changed['content'];
+ $this->replace($content, $child, $dom);
+ }
+ }
+ } else {
+ $content = trim($p->textContent);
+ if($content == '') {
+ continue;
+ }
+
+ $this->replace($content, $p, $dom);
+ }
}
- $dom->save($this->file);
+ $dom->save($filePath . "/document_sdapplied.xml");
+
+ return $filePath . "/document_sdapplied.xml";
+ }
+
+ /**
+ * Apply SD on document's paragraph
+ *
+ * @param string $content paragraph content
+ * @param $element DOM element
+ *
+ * @return void
+ */
+ protected function replace($content, $element, $dom) {
+ $search = new SearchAndDisplace(
+ stripslashes($content),
+ [
+ 'searchers' => $this->searchers,
+ ],
+ $this->searchOnly,
+ true
+ );
+
+ $changed = $search->execute();
+
+ if($changed) {
+ if($this->searchOnly) {
+ $content = $element->textContent;
+ $indexes = $changed;
+ } else {
+ $content = $changed['content'];
+ $indexes = $changed['indexes'];
+ }
+
+ foreach(array_keys($indexes) as $searcher) {
+ if(empty($indexes[$searcher])) {
+ continue;
+ }
+
+ foreach($indexes[$searcher] as $change) {
+ $first = substr($content, 0, $change['start']);
+ $changed = "" . substr($content, $change['start'], $change['end'] - $change['start'] + 1) . "";
+ $last = substr($content, $change['end'] + 1);
+
+ $element->textContent = $first;
+ $changed = $dom->createElement("text:span", $changed);
+ $last = $dom->createElement("text:span", $last);
+ // $changed->setAttribute('style', 'background-color: red');
+ $element->appendChild($changed);
+ $element->appendChild($last);
+ }
+ }
+ }
}
}
diff --git a/resources/js/components/ProcessFile/ProcessFile.ts b/resources/js/components/ProcessFile/ProcessFile.ts
index 77f8649..22aa76e 100644
--- a/resources/js/components/ProcessFile/ProcessFile.ts
+++ b/resources/js/components/ProcessFile/ProcessFile.ts
@@ -1,4 +1,3 @@
-import marked from 'marked';
import {Vue, Component, Prop, Watch} from 'vue-property-decorator';
import {FileData} from '@/interfaces/FileData';
import { eventBus } from '@/app';
@@ -357,7 +356,6 @@ export default class ProcessFile extends Vue {
private async runSearchersWithoutDisplacing() {
this.processing = true;
- this.processedFileContent = '';
let searchers: Array<{ key: string; type: string; value: string; }> = [];
@@ -370,10 +368,10 @@ export default class ProcessFile extends Vue {
});
try {
- const response = await this.$api.filterDocument(this.fileContent, searchers, true);
+ const response = await this.$api.filterDocument(this.file.id, searchers, true);
- this.processedFileContent = this.fileContent;
- this.documentDiffIndexes = response;
+ this.processedFileContent = response.content;
+ // this.documentDiffIndexes = response;
this.createDiffPreview();
this.processing = false;