Skip to content

Instantly share code, notes, and snippets.

@dimensi
Created July 24, 2019 15:27
Show Gist options
  • Save dimensi/32ce8a970aa299fdd5d970e22d58efc6 to your computer and use it in GitHub Desktop.
Save dimensi/32ce8a970aa299fdd5d970e22d58efc6 to your computer and use it in GitHub Desktop.
convert html to editor js readable format
<?php
use DOMDocument;
use DOMNode;
use DOMNodeList;
use Illuminate\Support\Collection;
final class HTML2EditorJS
{
private $document;
private $html;
private $result;
function __construct($html)
{
$this->html = $html;
$this->document = new DOMDocument();
if ($this->html) {
$this->document->loadHTML($this->html);
}
$this->result = [
'time' => time(),
'version' => "2.15.0",
'blocks' => []
];
}
public function toArray()
{
if (!$this->html) {
return $this->result;
}
$body = $this->document->getElementsByTagName('body');
$children = $this->getChildren($body->item(0));
$blocks = $children
->map(function (DOMNode $item) {
if ($item->nodeName === 'p') {
return $this->parseParagraph($item);
}
if (str_contains($item->nodeName, 'h')) {
return $this->parseHeader($item);
}
if ($item->nodeName === 'ol' || $item->nodeName === 'ul') {
return $this->parseList($item);
}
return null;
})
->filter(function ($item) {
return $item !== null;
})
->values()
->toArray();
$this->result['blocks'] = $blocks;
return $this->result;
}
/**
* @param DOMNode $p
* @return array
*/
private function parseParagraph($p)
{
return [
'type' => 'paragraph',
'data' => [
'text' => $this->saveTextFromNode($this->innerHTML($p))
]
];
}
/**
* @param DOMNode $header
* @return array
*/
private function parseHeader($header)
{
return [
'type' => 'header',
'data' => [
'text' => $this->saveTextFromNode($this->innerHTML($header)),
'level' => str_replace('h', '', $header->nodeName),
]
];
}
/**
* @param DOMNode $list
* @return array
*/
private function parseList($list)
{
return [
'type' => 'list',
'data' => [
'style' => $list->nodeName === 'ol' ? 'ordered' : 'unordered',
'items' => $this->getChildren($list)
->map(function (DOMNode $item) {
return $this->saveTextFromNode($this->innerHTML($item));
})->toArray()
]
];
}
/**
* @param string $text
* @return string
*/
private function saveTextFromNode($text)
{
return trim(utf8_decode($text));
}
/**
* @param DOMNode $node
* @return Collection<DOMNode>
*/
private function getChildren($node)
{
return $this->DOMListToCollection($node->childNodes);
}
/**
* @param DOMNodeList $domList
* @return Collection<DOMNode>
*/
private function DOMListToCollection($domList)
{
return collect(iterator_to_array($domList));
}
/**
* @param DOMNode $node
* @return string
*/
private function innerHTML($node)
{
return implode(
array_map(
[$node->ownerDocument, "saveHTML"],
iterator_to_array($node->childNodes)
)
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment