added controller to render markdown documentation #129
This commit is contained in:
25
src/Constants.php
Normal file
25
src/Constants.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App;
|
||||
|
||||
/**
|
||||
* Some very global constants for Kimai.
|
||||
*/
|
||||
class Constants
|
||||
{
|
||||
/**
|
||||
* Currently only used for informational purpose in the footer
|
||||
*/
|
||||
const VERSION = '2.0 dev';
|
||||
/**
|
||||
* Used in multiple views
|
||||
*/
|
||||
const GITHUB = 'https://github.com/kevinpapst/kimai2/';
|
||||
}
|
||||
83
src/Controller/HelpController.php
Normal file
83
src/Controller/HelpController.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Constants;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
|
||||
/**
|
||||
* This controller can render the markdown documentation from /var/docs/
|
||||
*
|
||||
* @Route("/help")
|
||||
* @Security("has_role('ROLE_USER')")
|
||||
*/
|
||||
class HelpController extends Controller
|
||||
{
|
||||
|
||||
const README = 'README';
|
||||
const DOCS_DIR = 'var/docs/';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $projectDirectory;
|
||||
|
||||
/**
|
||||
* HelpController constructor.
|
||||
* @param string $projectDirectory
|
||||
*/
|
||||
public function __construct(string $projectDirectory)
|
||||
{
|
||||
$this->projectDirectory = $projectDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/", defaults={"chapter": "README"}, name="help")
|
||||
* @Route("/{chapter}", requirements={"chapter": "[a-zA-Z]*"}, name="help_chapter")
|
||||
* @Method("GET")
|
||||
*
|
||||
* @param string $chapter
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function indexAction(?string $chapter)
|
||||
{
|
||||
$breadcrumb = [self::README];
|
||||
if ($chapter !== self::README) {
|
||||
$breadcrumb[] = $chapter;
|
||||
}
|
||||
|
||||
$chapterFile = $this->getFilenameForChapter($chapter);
|
||||
|
||||
if (!file_exists($chapterFile)) {
|
||||
throw $this->createNotFoundException('Documentation chapter not found: ' . $chapter);
|
||||
}
|
||||
|
||||
$content = file_get_contents($chapterFile);
|
||||
|
||||
return $this->render('help/index.html.twig', [
|
||||
'breadcrumb' => $breadcrumb,
|
||||
'chapter' => $chapter,
|
||||
'documentation' => $content,
|
||||
'github' => Constants::GITHUB
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $chapter
|
||||
* @return string
|
||||
*/
|
||||
protected function getFilenameForChapter(string $chapter)
|
||||
{
|
||||
return $this->projectDirectory . DIRECTORY_SEPARATOR . self::DOCS_DIR . $chapter . '.md';
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,10 @@ class AppFixtures extends Fixture
|
||||
use FixturesTrait;
|
||||
|
||||
const DEFAULT_PASSWORD = 'kitten';
|
||||
const USERNAME_USER = 'john_user';
|
||||
const USERNAME_TEAMLEAD = 'tony_teamlead';
|
||||
const USERNAME_ADMIN = 'anna_admin';
|
||||
const USERNAME_SUPER_ADMIN = 'susan_super';
|
||||
|
||||
/**
|
||||
* @var UserPasswordEncoderInterface
|
||||
@@ -93,7 +97,7 @@ class AppFixtures extends Fixture
|
||||
'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=monsterid&f=y', true
|
||||
],
|
||||
[
|
||||
'John Doe', 'Developer', 'john_user', 'john_user@example.com', 'ROLE_USER',
|
||||
'John Doe', 'Developer', self::USERNAME_USER, 'john_user@example.com', 'ROLE_USER',
|
||||
'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=retro&f=y', true
|
||||
],
|
||||
// inactive user to test login
|
||||
@@ -102,16 +106,16 @@ class AppFixtures extends Fixture
|
||||
'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=retro&f=y', false
|
||||
],
|
||||
[
|
||||
'Tony Maier', 'Head of Development', 'tony_teamlead', 'tony_teamlead@example.com', 'ROLE_TEAMLEAD',
|
||||
'Tony Maier', 'Head of Development', self::USERNAME_TEAMLEAD, 'tony_teamlead@example.com', 'ROLE_TEAMLEAD',
|
||||
'https://en.gravatar.com/userimage/3533186/bf2163b1dd23f3107a028af0195624e9.jpeg', true
|
||||
],
|
||||
// no avatar to test default image macro
|
||||
[
|
||||
'Anna Smith', 'Administrator', 'anna_admin', 'anna_admin@example.com', 'ROLE_ADMIN', null, true
|
||||
'Anna Smith', 'Administrator', self::USERNAME_ADMIN, 'anna_admin@example.com', 'ROLE_ADMIN', null, true
|
||||
],
|
||||
// no alias to test twig username macro
|
||||
[
|
||||
null, 'Super Administrator', 'susan_super', 'susan_super@example.com', 'ROLE_SUPER_ADMIN',
|
||||
null, 'Super Administrator', self::USERNAME_SUPER_ADMIN, 'susan_super@example.com', 'ROLE_SUPER_ADMIN',
|
||||
'/bundles/avanzuadmintheme/img/avatar.png', true
|
||||
]
|
||||
];
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace App\Twig;
|
||||
|
||||
use Symfony\Component\Intl\Intl;
|
||||
use App\Entity\Timesheet;
|
||||
use Twig\TwigFilter;
|
||||
|
||||
/**
|
||||
* Multiple Twig extensions: filters and functions
|
||||
@@ -37,11 +38,11 @@ class Extensions extends \Twig_Extension
|
||||
public function getFilters()
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFilter('duration', array($this, 'duration')),
|
||||
new \Twig_SimpleFilter('durationForEntry', array($this, 'durationForEntry')),
|
||||
new \Twig_SimpleFilter('money', array($this, 'money')),
|
||||
new \Twig_SimpleFilter('currency', array($this, 'currency')),
|
||||
new \Twig_SimpleFilter('country', array($this, 'country')),
|
||||
new TwigFilter('duration', [$this, 'duration']),
|
||||
new TwigFilter('durationForEntry', [$this, 'durationForEntry']),
|
||||
new TwigFilter('money', [$this, 'money']),
|
||||
new TwigFilter('currency', [$this, 'currency']),
|
||||
new TwigFilter('country', [$this, 'country']),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -140,12 +141,4 @@ class Extensions extends \Twig_Extension
|
||||
|
||||
return $locales;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'kimai.extension';
|
||||
}
|
||||
}
|
||||
|
||||
54
src/Twig/MarkdownExtension.php
Normal file
54
src/Twig/MarkdownExtension.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Twig;
|
||||
|
||||
use App\Utils\Markdown;
|
||||
use Twig\TwigFilter;
|
||||
|
||||
/**
|
||||
* A twig extension to handle markdown parser.
|
||||
*/
|
||||
class MarkdownExtension extends \Twig_Extension
|
||||
{
|
||||
/**
|
||||
* @var Markdown
|
||||
*/
|
||||
private $markdown;
|
||||
|
||||
/**
|
||||
* MarkdownExtension constructor.
|
||||
* @param Markdown $parser
|
||||
*/
|
||||
public function __construct(Markdown $parser)
|
||||
{
|
||||
$this->markdown = $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFilter[]
|
||||
*/
|
||||
public function getFilters()
|
||||
{
|
||||
return [
|
||||
new TwigFilter('md2html', [$this, 'markdownToHtml'], ['is_safe' => ['html']]),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the given Markdown content into HTML
|
||||
*
|
||||
* @param string $content
|
||||
* @return string
|
||||
*/
|
||||
public function markdownToHtml(string $content): string
|
||||
{
|
||||
return $this->markdown->toHtml($content);
|
||||
}
|
||||
}
|
||||
41
src/Utils/Markdown.php
Normal file
41
src/Utils/Markdown.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Utils;
|
||||
|
||||
use Parsedown as MarkdownParser;
|
||||
|
||||
/**
|
||||
* A simple class to parse markdown syntax and return HTML.
|
||||
*/
|
||||
class Markdown
|
||||
{
|
||||
|
||||
/**
|
||||
* @var MarkdownParser
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* Markdown constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->parser = new MarkdownParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
public function toHtml(string $text): string
|
||||
{
|
||||
return $this->parser->text($text);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user