-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1785 from tomudding/feature/improved-markdown-sup…
…port-for-companies Improved markdown support for companies
- Loading branch information
Showing
40 changed files
with
863 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
module/Application/src/Extensions/CommonMark/CompanyImage/CompanyImageExtension.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Application\Extensions\CommonMark\CompanyImage; | ||
|
||
use Application\View\Helper\GlideUrl; | ||
use League\CommonMark\Environment\EnvironmentBuilderInterface; | ||
use League\CommonMark\Extension\CommonMark\Node\Inline\Image; | ||
use League\CommonMark\Extension\CommonMark\Renderer\Inline\ImageRenderer; | ||
use League\CommonMark\Extension\ExtensionInterface; | ||
use Override; | ||
|
||
class CompanyImageExtension implements ExtensionInterface | ||
{ | ||
public function __construct(private readonly GlideUrl $glideUrl) | ||
{ | ||
} | ||
|
||
#[Override] | ||
public function register(EnvironmentBuilderInterface $environment): void | ||
{ | ||
$environment->addRenderer( | ||
Image::class, | ||
new CompanyImageRenderer($environment->getConfiguration(), new ImageRenderer(), $this->glideUrl), | ||
10, | ||
); | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
module/Application/src/Extensions/CommonMark/CompanyImage/CompanyImageRenderer.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Application\Extensions\CommonMark\CompanyImage; | ||
|
||
use Application\View\Helper\GlideUrl; | ||
use League\CommonMark\Extension\CommonMark\Node\Inline\Image; | ||
use League\CommonMark\Extension\CommonMark\Renderer\Inline\ImageRenderer; | ||
use League\CommonMark\Node\Node; | ||
use League\CommonMark\Renderer\ChildNodeRendererInterface; | ||
use League\CommonMark\Renderer\NodeRendererInterface; | ||
use League\CommonMark\Util\HtmlElement; | ||
use League\Config\ConfigurationInterface; | ||
use Stringable; | ||
|
||
use function str_starts_with; | ||
use function substr; | ||
|
||
class CompanyImageRenderer implements NodeRendererInterface | ||
{ | ||
public function __construct( | ||
private readonly ConfigurationInterface $config, | ||
private readonly ImageRenderer $baseImageRenderer, | ||
private readonly GlideUrl $glideUrl, | ||
) { | ||
} | ||
|
||
public function render( | ||
Node $node, | ||
ChildNodeRendererInterface $childRenderer, | ||
): Stringable|string { | ||
Image::assertInstanceOf($node); | ||
|
||
// phpcs:ignore SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable | ||
/** @var Image $node */ | ||
|
||
// Check if we have a valid image, only accept images that were uploaded specifically for companies. | ||
if (!str_starts_with($node->getUrl(), '/data/company/')) { | ||
return ''; | ||
} | ||
|
||
$this->baseImageRenderer->setConfiguration($this->config); | ||
/** @var HtmlElement $imageElement */ | ||
$imageElement = $this->baseImageRenderer->render($node, $childRenderer); | ||
|
||
$imageElement->setAttribute('style', 'max-width: 100%'); | ||
$imageElement->setAttribute('src', $this->glideUrl->getUrl(substr($node->getUrl(), 5), [])); | ||
|
||
return $imageElement; | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
module/Application/src/Extensions/CommonMark/NoImage/NoImageExtension.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Application\Extensions\CommonMark\NoImage; | ||
|
||
use League\CommonMark\Environment\EnvironmentBuilderInterface; | ||
use League\CommonMark\Extension\CommonMark\Node\Inline\Image; | ||
use League\CommonMark\Extension\ExtensionInterface; | ||
use Override; | ||
|
||
class NoImageExtension implements ExtensionInterface | ||
{ | ||
#[Override] | ||
public function register(EnvironmentBuilderInterface $environment): void | ||
{ | ||
$environment->addRenderer(Image::class, new NoImageRenderer(), 10); | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
module/Application/src/Extensions/CommonMark/NoImage/NoImageRenderer.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Application\Extensions\CommonMark\NoImage; | ||
|
||
use League\CommonMark\Extension\CommonMark\Node\Inline\Image; | ||
use League\CommonMark\Node\Node; | ||
use League\CommonMark\Renderer\ChildNodeRendererInterface; | ||
use League\CommonMark\Renderer\NodeRendererInterface; | ||
|
||
use function sprintf; | ||
|
||
class NoImageRenderer implements NodeRendererInterface | ||
{ | ||
public function render( | ||
Node $node, | ||
ChildNodeRendererInterface $childRenderer, | ||
): string { | ||
Image::assertInstanceOf($node); | ||
|
||
// phpcs:ignore SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable | ||
/** @var Image $node */ | ||
|
||
return sprintf( | ||
'![%s](%s)', | ||
$node->getTitle() ?? '', | ||
$node->getUrl(), | ||
); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
module/Application/src/Extensions/CommonMark/VideoIframe/Parsers/VimeoUrlParser.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Application\Extensions\CommonMark\VideoIframe\Parsers; | ||
|
||
use Application\Extensions\CommonMark\VideoIframe\Video; | ||
use Application\Extensions\CommonMark\VideoIframe\VideoPlatforms; | ||
use Application\Extensions\CommonMark\VideoIframe\VideoUrlParserInterface; | ||
use Override; | ||
|
||
use function preg_match; | ||
|
||
class VimeoUrlParser implements VideoUrlParserInterface | ||
{ | ||
private const REGEX = '/(?:vimeo\.com\/(?:\d+|[^\/]+\/[^\/]+\/video\/|album\/[^\/]+\/video\/|channels\/[^\/]+\/|groups\/[^\/]+\/videos\/|ondemand\/[^\/]+\/)|player\.vimeo\.com\/video\/)(\d+)/'; | ||
|
||
#[Override] | ||
public function parse(string $url): ?Video | ||
{ | ||
if (preg_match(self::REGEX, $url, $matches)) { | ||
return new Video(VideoPlatforms::Vimeo, $matches[1]); | ||
} | ||
|
||
return null; | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
module/Application/src/Extensions/CommonMark/VideoIframe/Parsers/YouTubeUrlParser.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Application\Extensions\CommonMark\VideoIframe\Parsers; | ||
|
||
use Application\Extensions\CommonMark\VideoIframe\Video; | ||
use Application\Extensions\CommonMark\VideoIframe\VideoPlatforms; | ||
use Application\Extensions\CommonMark\VideoIframe\VideoUrlParserInterface; | ||
use Override; | ||
|
||
use function preg_match; | ||
|
||
class YouTubeUrlParser implements VideoUrlParserInterface | ||
{ | ||
private const REGEX = '/(?:m\.)?(?:youtube\.com\/(?:watch\?v=|v\/|embed\/)|youtu\.be\/|youtube-nocookie\.com\/embed\/)([\w-]+)/'; | ||
|
||
#[Override] | ||
public function parse(string $url): ?Video | ||
{ | ||
if (preg_match(self::REGEX, $url, $matches)) { | ||
return new Video(VideoPlatforms::YouTube, $matches[1]); | ||
} | ||
|
||
return null; | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
module/Application/src/Extensions/CommonMark/VideoIframe/Video.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Application\Extensions\CommonMark\VideoIframe; | ||
|
||
class Video | ||
{ | ||
public function __construct( | ||
private readonly VideoPlatforms $platform, | ||
private readonly string $identifier, | ||
) { | ||
} | ||
|
||
public function getPlatform(): VideoPlatforms | ||
{ | ||
return $this->platform; | ||
} | ||
|
||
public function getIdentifier(): string | ||
{ | ||
return $this->identifier; | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
module/Application/src/Extensions/CommonMark/VideoIframe/VideoIframe.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Application\Extensions\CommonMark\VideoIframe; | ||
|
||
use League\CommonMark\Node\Node; | ||
|
||
class VideoIframe extends Node | ||
{ | ||
public function __construct(private readonly Video $video) | ||
{ | ||
parent::__construct(); | ||
} | ||
|
||
public function getVideo(): Video | ||
{ | ||
return $this->video; | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
module/Application/src/Extensions/CommonMark/VideoIframe/VideoIframeExtension.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Application\Extensions\CommonMark\VideoIframe; | ||
|
||
use Application\Extensions\CommonMark\VideoIframe\Parsers\VimeoUrlParser; | ||
use Application\Extensions\CommonMark\VideoIframe\Parsers\YouTubeUrlParser; | ||
use League\CommonMark\Environment\EnvironmentBuilderInterface; | ||
use League\CommonMark\Event\DocumentParsedEvent; | ||
use League\CommonMark\Extension\ExtensionInterface; | ||
use Override; | ||
|
||
class VideoIframeExtension implements ExtensionInterface | ||
{ | ||
#[Override] | ||
public function register(EnvironmentBuilderInterface $environment): void | ||
{ | ||
$environment->addEventListener( | ||
DocumentParsedEvent::class, | ||
new VideoIframeProcessor([ | ||
new VimeoUrlParser(), | ||
new YouTubeUrlParser(), | ||
]), | ||
) | ||
->addRenderer(VideoIframe::class, new VideoIframeRenderer(), 10); | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
module/Application/src/Extensions/CommonMark/VideoIframe/VideoIframeProcessor.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Application\Extensions\CommonMark\VideoIframe; | ||
|
||
use League\CommonMark\Event\DocumentParsedEvent; | ||
use League\CommonMark\Extension\CommonMark\Node\Inline\Link; | ||
|
||
class VideoIframeProcessor | ||
{ | ||
/** | ||
* @param VideoUrlParserInterface[] $parsers | ||
*/ | ||
public function __construct(private readonly array $parsers) | ||
{ | ||
} | ||
|
||
public function __invoke(DocumentParsedEvent $event): void | ||
{ | ||
$walker = $event->getDocument()->walker(); | ||
|
||
while ($item = $walker->next()) { | ||
$link = $item->getNode(); | ||
|
||
if (!($link instanceof Link)) { | ||
continue; | ||
} | ||
|
||
foreach ($this->parsers as $parser) { | ||
$video = $parser->parse($link->getUrl()); | ||
|
||
if (null === $video) { | ||
continue; | ||
} | ||
|
||
$link->replaceWith(new VideoIframe($video)); | ||
} | ||
} | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
module/Application/src/Extensions/CommonMark/VideoIframe/VideoIframeRenderer.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Application\Extensions\CommonMark\VideoIframe; | ||
|
||
use League\CommonMark\Node\Node; | ||
use League\CommonMark\Renderer\ChildNodeRendererInterface; | ||
use League\CommonMark\Renderer\NodeRendererInterface; | ||
use League\CommonMark\Util\HtmlElement; | ||
use Override; | ||
use Stringable; | ||
|
||
class VideoIframeRenderer implements NodeRendererInterface | ||
{ | ||
#[Override] | ||
public function render( | ||
Node $node, | ||
ChildNodeRendererInterface $childRenderer, | ||
): Stringable { | ||
VideoIframe::assertInstanceOf($node); | ||
|
||
// phpcs:ignore SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable | ||
/** @var VideoIframe $node */ | ||
$video = $node->getVideo(); | ||
|
||
return new HtmlElement( | ||
'div', | ||
['style' => 'position: relative; height: 0; padding-bottom: 56.2493%;'], | ||
new HtmlElement('iframe', [ | ||
'allowfullscreen' => '1', | ||
'src' => $video->getPlatform()->getUrl($video->getIdentifier()), | ||
'style' => 'position: absolute; width: 100%; height: 100%; top: 0; left: 0; border: 0;', | ||
]), | ||
); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
module/Application/src/Extensions/CommonMark/VideoIframe/VideoPlatforms.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Application\Extensions\CommonMark\VideoIframe; | ||
|
||
enum VideoPlatforms: string | ||
{ | ||
case Vimeo = 'vimeo'; | ||
case YouTube = 'youtube'; | ||
|
||
public function getUrl(string $identifier): string | ||
{ | ||
return match ($this) { | ||
self::Vimeo => 'https://player.vimeo.com/video/' . $identifier, | ||
self::YouTube => 'https://www.youtube-nocookie.com/embed/' . $identifier, | ||
}; | ||
} | ||
} |
Oops, something went wrong.