project_wiki-1.x-dev/modules/project_wiki_markdown_content/src/Plugin/ProjectWikiMarkdownContentPluginBase.php

modules/project_wiki_markdown_content/src/Plugin/ProjectWikiMarkdownContentPluginBase.php
<?php

namespace Drupal\project_wiki_markdown_content\Plugin;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\project_wiki\Plugin\ProjectWikiContentPluginBase;
use Drupal\project_wiki\ProjectWikiValueObject;
use League\CommonMark\CommonMarkConverter;
use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
use League\CommonMark\Output\RenderedContentInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * The PluginBase for the Markdown services.
 */
abstract class ProjectWikiMarkdownContentPluginBase extends ProjectWikiContentPluginBase implements ContainerFactoryPluginInterface {
  use StringTranslationTrait;

  /**
   * The module handler service.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The file system service.
   *
   * @var \Drupal\Core\File\FileSystemInterface
   */
  protected $fileSystem;

  /**
   * The module config.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  protected $config;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler, FileSystemInterface $file_system, ConfigFactoryInterface $config_factory) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $module_handler);
    $this->moduleHandler = $module_handler;
    $this->fileSystem = $file_system;
    $this->config = $config_factory->get('project_wiki_markdown_content.settings');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('module_handler'),
      $container->get('file_system'),
      $container->get('config.factory'),
    );
  }

  /**
   * Abstract definition for the function providing directory path.
   */
  abstract public function getEntriesDirectoryPath();

  /**
   * {@inheritdoc}
   */
  public function getValueObjects(): array {
    $entries = [];
    $searchDir = $this->getEntriesDirectoryPath();
    $files = $this->readMarkdownDirectories($searchDir);
    foreach ($files as $file) {
      $langcode = explode(DIRECTORY_SEPARATOR, str_replace($searchDir . DIRECTORY_SEPARATOR, '', $file->uri), 2)[0];
      $category = explode(DIRECTORY_SEPARATOR, explode(DIRECTORY_SEPARATOR, str_replace($searchDir . DIRECTORY_SEPARATOR, '', $file->uri) ?? '', 2)[1] ?? '', 2)[0];
      if (str_ends_with($category, '.md')) {
        $category = NULL;
      }
      // Turn markdown into HTML and read header data:
      $entries[] = $this->prepareMarkdown($file, $langcode ?: NULL, $category ?: NULL);
    }
    return $entries;
  }

  /**
   * Returns all markdown files in the given directory and its subdirectories.
   *
   * @param string $searchDir
   *   The directory to search in.
   * @param string $mask
   *   The mask to search by (.md files are the default).
   *
   * @return array
   *   The list of files.
   */
  public function readMarkdownDirectories(string $searchDir, $mask = "/\.md$/"): array {
    $files = [];
    $allFiles = [];
    if (is_dir($searchDir)) {
      $allFiles = $this->fileSystem->scanDirectory($searchDir, $mask);
    }
    else {
      throw new \Exception('Directory not found: "' . $searchDir . '"');
    }
    foreach ($allFiles as $file) {
      if (file_exists($file->uri)) {
        $files[] = $file;
      }
    }
    return $files;
  }

  /**
   * Prepares a markdown file.
   *
   * Reads and prepares the given markdown file to turn it into an
   * ProjectWikiEntityContentValueObject.
   */
  public function prepareMarkdown($file, $langcode = NULL, $category = NULL) : ProjectWikiValueObject {
    // Get the markdown file contents:
    $fileContents = file_get_contents($file->uri);
    // Parse the markdown to a RenderedContent instance:
    $renderedContent = $this->parseMarkdown($fileContents);
    // Get markdown metadata and declare required variables:
    $metaData = $renderedContent->getFrontMatter();
    $isDeveloperContent = !empty($metaData['isDeveloperContent']) ? $metaData['isDeveloperContent'] : FALSE;
    $title = !empty($metaData['title']) ? $metaData['title'] : $file->name;
    $provider = 'project_wiki_markdown_content';
    $id = $file->uri;

    // Note, that if filterFormat is NULL, "filter_fallback_format()" is used.
    $filteredContent = check_markup($renderedContent->getContent(), $this->config->get('filterFormat'), $langcode);

    return new ProjectWikiValueObject($provider, $id, $langcode, $category, $title, $filteredContent, $isDeveloperContent);
  }

  /**
   * Helper function to convert markdown into a RenderedContent instance.
   *
   * @param string $markdown
   *   The markdown string to parse.
   */
  public function parseMarkdown(string $markdown): RenderedContentInterface {
    $converter = new CommonMarkConverter();
    $converter->getEnvironment()->addExtension(new FrontMatterExtension());
    return $converter->convert($markdown);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc