. * */ /* Cli example: php cli.php admin module=plugins/markdown-import/settings action=import site_id=5 settings[path]=/docs/user */ namespace Vvveb\Plugins\MarkdownImport\Controller; use function Vvveb\__; use Vvveb\Controller\Base; use function Vvveb\htmlToText; use function Vvveb\model; use Vvveb\Plugins\MarkdownImport\System\Parsedown as Parsedown; use Vvveb\Sql\categorySQL; use Vvveb\Sql\postSQL; use Vvveb\System\Extensions\Extensions; class Settings extends Base { private $cats = []; protected $type = 'post'; //can be also product private function markdownHtml($markdown, $dir) { //escape html tags //$markdown = str_replace(['<', '>'], ['<', '>'], $markdown); //escape code blocks $markdown = preg_replace_callback('/```.*?```/ms', function ($matches) { return str_replace(['<', '>'], ['<', '>'], $matches[0]); }, $markdown); /* $markdown = preg_replace_callback('/```.*?```/ms', function ($matches) { return htmlentities($matches[0]); }, $markdown);*/ //echo $markdown; $html = $text = $this->parsedown->text($markdown); //admonitions support $html = preg_replace_callback('/

:::(\w+)<\/p>(.*?)\n

:::<\/p>/ms', function ($matches) { $text = $matches[1]; $type = str_replace(['info', 'tip', 'note', 'caution', 'danger'], ['primary', 'info', 'secondary', 'warning', 'danger'], $text); $icon = str_replace(['primary', 'info', 'secondary', 'warning', 'danger'], ['🛈', '💡', 'ℹ', ' 🛆', '🛇'], $type); $message = strip_tags($matches[2], ''); return '

'; }, $html); //process images $mediaPath = PUBLIC_PATH . 'media/'; @mkdir(DIR_ROOT . $mediaPath . 'docs/'); $html = preg_replace_callback('/"; //check and add dir $this->addCategories($dir . DS . $file); $this->traverseDir($dir . DS . $file); chdir($dir); } } else { if ($file != '.' && $file != '..' && strrpos($file, '.md') != false) { //add post $this->add($file,$dir . DS . $file, $dir); } } } closedir($dp); return true; } private function addCategories($file) { $folder = trim(str_replace($this->docs_folder, '', $file), ' /' . DS); //echo '
'; $cats = explode(DS, $folder); $prev_category = 0; $category_id = 0; foreach ($cats as $category_slug) { $cat = $this->categories->getCategoryBySlug(['slug' => $category_slug, 'taxonomy_id' => 1, 'parent_id' => $prev_category, 'site_id' => $this->global['site_id']]); if ($cat) { $prev_category = $cat['taxonomy_item_id']; } else { $cat = $this->categories->addCategory([ 'taxonomy_item' => $this->global + [ 'parent_id' => $prev_category, 'taxonomy_id' => 1, ], 'taxonomy_item_content' => $this->global + ['slug'=> $category_slug, 'name' => \Vvveb\humanReadable($category_slug), 'content' => ''], ] + $this->global); $category_id = $cat['taxonomy_item']; } } if (! $category_id) { $category_id = $prev_category; } if (! isset($this->cats[$folder])) { $this->cats[$folder] = $category_id; } } private function add($filename, $file, $dir) { $category = trim(str_replace($this->docs_folder, '', dirname($file)), ' /' . DS); $slug = \Vvveb\filter('/([^.]+)/', basename($file)); $name = \Vvveb\humanReadable($slug); $slug = \Vvveb\filter('/([^.]+)/', basename($file)); $name = \Vvveb\humanReadable($slug); $markdown = file_get_contents($file); //get parameters and remove $params = []; $markdown = preg_replace_callback('@^\s*---.+?---\s*@ms', function ($matches) use (&$params) { $params = Extensions::getParams($matches[0]); return ''; }, $markdown); //convert markdown to html $html = $this->markdownHtml($markdown, $dir); //get name from heading 1 if available $html = preg_replace_callback('/

(.+?)<\/h1>/', function ($match) use (&$name) { $name = $match[1]; return ''; //remove heading 1 from content as it will be set as post name },$html); $category_id = $this->cats[$category] ?? false; $slug = $params['slug'] ?? $slug; $post_data = $this->post->get(['slug' => $slug]); $excerpt = substr(htmlToText($html), 0, 200) ?? ''; if (defined('CLI')) { echo "Importing $slug - $file\n"; } $language_id = $this->global['language_id']; if (! $post_data) { $data = [ 'post' => $this->global + $params, 'post_content' => [ $language_id => $params + ['language_id' => $language_id, 'name' => $name, 'slug' => $slug, 'content' => $html, 'excerpt' => $excerpt], ], 'site_id' => [$this->global['site_id']], ] + $this->global; $post_data = $this->post->add($data); if ($category_id) { $taxonomy_item = ['post_id' => $post_data['post'], 'taxonomy_item' => ['taxonomy_item_id' => $category_id]]; $this->post->setPostTaxonomy($taxonomy_item); } } else { $data = [ 'post' => $this->global + $params, 'post_content' => [ $language_id => $params + ['language_id' => $language_id, 'name' => $name, 'slug' => $slug, 'content' => $html, 'excerpt' => $excerpt], ], 'post_id' => $post_data['post_id'], 'site_id' => [$this->global['site_id']], ] + $this->global; $result = $this->post->edit($data); if ($category_id) { $taxonomy_item = ['post_id' => $post_data['post_id'], 'taxonomy_item' => ['taxonomy_item_id' => $category_id]]; $this->post->setPostTaxonomy($taxonomy_item); } } } function import() { $path = $this->request->post['settings']['path']; if (isset($this->request->post['site_id'])) { $this->global['site_id'] = $this->request->post['site_id']; } if (isset($this->request->get['site_id'])) { $this->global['site_id'] = $this->request->get['site_id']; } if (isset($this->request->get['type'])) { $this->type = $this->request->get['type']; } if ($path) { $this->docs_folder = DIR_ROOT . $path . DS; $this->categories = new categorySQL(); $this->post = model($this->type); //new postSQL(); /* include __DIR__ . '/../../system/parsedown.php'; $this->parsedown = new \Parsedown(); */ $this->parsedown = new Parsedown(); if ($this->traverseDir($this->docs_folder)) { $this->view->success[] = __('Import complete!'); } } return $this->index(); } function index() { //$cat = $categories->getCategoryBySlug(['slug' => 'desktop', 'parent_id' => 1]); //$this->traverseDir($this->docs_folder); return null; } }