Apply Mentions everywhere (#595)
* variables and mentions * fix lint * add missing changes * fix tests * update quilly, fix bugs * fix lint * apply fixes * apply fixes * Fix MentionParser * Apply Mentions everywhere * Fix MentionParserTest * Small refactoring * Fixing quill import issues * Polished email integration, added customer sender mail * Add missing changes * improve migration command --------- Co-authored-by: Frank <csskfaves@gmail.com> Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
97
api/app/Open/MentionParser.php
Normal file
97
api/app/Open/MentionParser.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace App\Open;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMXPath;
|
||||
|
||||
class MentionParser
|
||||
{
|
||||
private $content;
|
||||
private $data;
|
||||
|
||||
public function __construct($content, $data)
|
||||
{
|
||||
$this->content = $content;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function parse()
|
||||
{
|
||||
$doc = new DOMDocument();
|
||||
// Disable libxml errors and use internal errors
|
||||
$internalErrors = libxml_use_internal_errors(true);
|
||||
|
||||
// Wrap the content in a root element to ensure it's valid XML
|
||||
$wrappedContent = '<root>' . $this->content . '</root>';
|
||||
|
||||
// Load HTML, using UTF-8 encoding
|
||||
$doc->loadHTML(mb_convert_encoding($wrappedContent, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
|
||||
// Restore libxml error handling
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
|
||||
$xpath = new DOMXPath($doc);
|
||||
$mentionElements = $xpath->query("//span[@mention]");
|
||||
|
||||
foreach ($mentionElements as $element) {
|
||||
$fieldId = $element->getAttribute('mention-field-id');
|
||||
$fallback = $element->getAttribute('mention-fallback');
|
||||
$value = $this->getData($fieldId);
|
||||
|
||||
if ($value !== null) {
|
||||
$textNode = $doc->createTextNode(is_array($value) ? implode(', ', $value) : $value);
|
||||
$element->parentNode->replaceChild($textNode, $element);
|
||||
} elseif ($fallback) {
|
||||
$textNode = $doc->createTextNode($fallback);
|
||||
$element->parentNode->replaceChild($textNode, $element);
|
||||
} else {
|
||||
$element->parentNode->removeChild($element);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract and return the processed HTML content
|
||||
$result = $doc->saveHTML($doc->getElementsByTagName('root')->item(0));
|
||||
|
||||
// Remove the root tags we added
|
||||
$result = preg_replace('/<\/?root>/', '', $result);
|
||||
|
||||
// Trim whitespace and convert HTML entities back to UTF-8 characters
|
||||
$result = trim(html_entity_decode($result, ENT_QUOTES | ENT_HTML5, 'UTF-8'));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function replaceMentions()
|
||||
{
|
||||
$pattern = '/<span[^>]*mention-field-id="([^"]*)"[^>]*mention-fallback="([^"]*)"[^>]*>.*?<\/span>/';
|
||||
return preg_replace_callback($pattern, function ($matches) {
|
||||
$fieldId = $matches[1];
|
||||
$fallback = $matches[2];
|
||||
$value = $this->getData($fieldId);
|
||||
|
||||
if ($value !== null) {
|
||||
if (is_array($value)) {
|
||||
return implode(' ', array_map(function ($v) {
|
||||
return $v;
|
||||
}, $value));
|
||||
}
|
||||
return $value;
|
||||
} elseif ($fallback) {
|
||||
return $fallback;
|
||||
}
|
||||
return '';
|
||||
}, $this->content);
|
||||
}
|
||||
|
||||
private function getData($fieldId)
|
||||
{
|
||||
$value = collect($this->data)->firstWhere('id', $fieldId)['value'] ?? null;
|
||||
|
||||
if (is_object($value)) {
|
||||
return (array) $value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user