updated dependencies to the latest versions also took a swing at rendering performance, which was pretty basic. it was fine for sites with not that many pages, but it gets a bit stick above 50 as of right now, performance has been improved slighthy by forcing some garbage collection, rendering 65 pages in under 30 seconds with 256MB available. the issue seems to the speed of initial page collections from the directories and then converting them to objects that the system can use. going to explore some options to optimize that particular script also removed page load from PageRepository instantion because when the app loads, it was calling that class as part of the start of process and loading pages everytime no matter what page was being looked at. removing that made non page sections snappier
187 lines
6.8 KiB
PHP
187 lines
6.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Data;
|
|
|
|
use League\CommonMark\MarkdownConverter;
|
|
use League\CommonMark\Environment\Environment;
|
|
use League\CommonMark\Extension\Table\TableExtension;
|
|
use League\CommonMark\Extension\Attributes\AttributesExtension;
|
|
use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
|
|
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
|
|
use League\CommonMark\Extension\Strikethrough\StrikethroughExtension;
|
|
use League\CommonMark\Extension\FrontMatter\Output\RenderedContentWithFrontMatter;
|
|
use Symfony\Component\HtmlSanitizer\HtmlSanitizerConfig;
|
|
use Symfony\Component\HtmlSanitizer\HtmlSanitizer;
|
|
|
|
class ContentService
|
|
{
|
|
protected $files = [];
|
|
protected $config = [];
|
|
protected $environment;
|
|
protected $converter;
|
|
protected $pageCount = "";
|
|
|
|
public function __construct()
|
|
{
|
|
//set up conversion handler
|
|
$this->environment = new Environment($this->config);
|
|
$this->environment->addExtension(new CommonMarkCoreExtension());
|
|
// Add the extension
|
|
$this->environment->addExtension(new FrontMatterExtension());
|
|
|
|
//Add Strikethrough rendering
|
|
$this->environment->addExtension(new StrikethroughExtension());
|
|
|
|
//add attributes to elements in markdown
|
|
$this->environment->addExtension(new AttributesExtension());
|
|
|
|
//add table rendering
|
|
$this->environment->addExtension(new TableExtension());
|
|
|
|
// Instantiate the converter engine and start converting some Markdown!
|
|
$this->converter = new MarkdownConverter($this->environment);
|
|
|
|
$this->loadPages(env('PAGES_PATH'));
|
|
}
|
|
|
|
public function loadPages($folder)
|
|
{
|
|
$folders = glob("$folder/*", GLOB_ONLYDIR);
|
|
foreach ($folders as $folder) {
|
|
//$this->files[] = $folder . "/";
|
|
$this->loadPages($folder);
|
|
}
|
|
$files = array_filter(glob("$folder/*md"), 'is_file');
|
|
foreach ($files as $file) {
|
|
$this->files[] = $file;
|
|
}
|
|
|
|
$this->pageCount = count($this->files);
|
|
}
|
|
|
|
public function loadAllPages()
|
|
{
|
|
$contents = [];
|
|
foreach ($this->files as $file) {
|
|
//get meta and html from file
|
|
$result = $this->converter->convert(file_get_contents($file));
|
|
$meta = [];
|
|
if ($result instanceof RenderedContentWithFrontMatter) {
|
|
$meta = $result->getFrontMatter();
|
|
}
|
|
|
|
//get raw markdown from file
|
|
$frontMatterExtension = new FrontMatterExtension();
|
|
$parsed = $frontMatterExtension
|
|
->getFrontMatterParser()
|
|
->parse(file_get_contents($file));
|
|
|
|
//never trust the front end. clean it up
|
|
|
|
$soap = (new HtmlSanitizerConfig())
|
|
// Allow "safe" elements and attributes. All scripts will be removed
|
|
// as well as other dangerous behaviors like CSS injection
|
|
->allowSafeElements()
|
|
->allowElement('div', ['class', 'title', 'id', 'style'])
|
|
->allowElement('img', ['src', 'alt', 'title', 'class'])
|
|
->allowElement('iframe', ['height', 'width', 'title', 'src'])
|
|
->allowElement('table')
|
|
->allowElement('li')
|
|
->allowRelativeMedias()
|
|
->allowRelativeLinks();
|
|
|
|
$laundry = new HtmlSanitizer($soap);
|
|
$scrubbed = $laundry->sanitize($result->getContent());
|
|
unset($result);
|
|
if (isset($meta['feature'])) {
|
|
$featureList = explode(',', $meta['feature']);
|
|
} else {
|
|
$featureList = "";
|
|
}
|
|
|
|
$docs = '';
|
|
if (isset($meta['files'])) {
|
|
$fileList = explode(',', $meta['files']);
|
|
$docs = $meta['files'];
|
|
} else {
|
|
$fileList = [];
|
|
$docs = '';
|
|
}
|
|
|
|
$media = [];
|
|
$files = [];
|
|
if ($featureList != '') {
|
|
foreach ($featureList as $file) {
|
|
$item = trim($file);
|
|
$ext = pathinfo($item, PATHINFO_EXTENSION);
|
|
if ($item != null || $item != '') {
|
|
array_push($media, ['file' => $item, 'type' => trim($ext)]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($fileList != "") {
|
|
foreach ($fileList as $file) {
|
|
$item = trim($file);
|
|
$ext = pathinfo($item, PATHINFO_EXTENSION);
|
|
if ($item != null || $item != '') {
|
|
array_push($files, ['file' => $item, 'type' => trim($ext)]);
|
|
}
|
|
}
|
|
}
|
|
//sort attributes into page object
|
|
$page = [
|
|
'id' => $meta['id'],
|
|
'uuid' => $meta['uuid'],
|
|
'title' => $meta['title'],
|
|
'feature' => $meta['feature'],
|
|
'files' => $docs,
|
|
'path' => $meta['path'],
|
|
'layout' => $meta['layout'],
|
|
'tags' => $meta['tags'],
|
|
'author' => $meta['author'],
|
|
'created' => date('Y M D d', $meta['created']),
|
|
'updated' => date('Y M D d', $meta['updated']),
|
|
'rawCreated' => $meta['created'],
|
|
'rawUpdated' => $meta['updated'],
|
|
'createdYear' => date('Y', $meta['created']),
|
|
'createdMonth' => date('m', $meta['created']),
|
|
'deleted' => $meta['deleted'],
|
|
'menu' => $meta['menu'],
|
|
'featured' => $meta['featured'],
|
|
'published' => $meta['published'],
|
|
'slug' => $meta['slug'],
|
|
'filePath' => $file,
|
|
'content' => $parsed->getContent(),
|
|
'html' => $scrubbed,
|
|
'media' => $media,
|
|
'docs' => $files
|
|
];
|
|
//checks for duplicates
|
|
$uuid = $meta['uuid'];
|
|
$found = current(
|
|
array_filter($contents, function ($item) use ($uuid) {
|
|
return isset($item['uuid']) && $uuid == $item['uuid'];
|
|
})
|
|
);
|
|
|
|
// if uuid is not present, add it
|
|
if (!$found) {
|
|
array_push($contents, $page);
|
|
}
|
|
unset($file);
|
|
gc_collect_cycles();
|
|
}
|
|
$collection = collect($contents);
|
|
$sorted = $collection->sortBy([
|
|
['id', 'desc'],
|
|
]);
|
|
$sorted->values()->all();
|
|
return $sorted;
|
|
}
|
|
|
|
public static function getAll()
|
|
{
|
|
echo("YES");
|
|
}
|
|
}
|