diff --git a/app/Entities/Episode.php b/app/Entities/Episode.php index 1b1c0e0f213362338f1650e3d1a9b29a2c08e187..3f1d33ff42a61f73db7d203b37403fff09935a59 100644 --- a/app/Entities/Episode.php +++ b/app/Entities/Episode.php @@ -26,7 +26,12 @@ use CodeIgniter\Entity\Entity; use CodeIgniter\Files\File; use CodeIgniter\HTTP\Files\UploadedFile; use CodeIgniter\I18n\Time; -use League\CommonMark\CommonMarkConverter; +use League\CommonMark\Environment\Environment; +use League\CommonMark\Extension\Autolink\AutolinkExtension; +use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension; +use League\CommonMark\Extension\DisallowedRawHtml\DisallowedRawHtmlExtension; +use League\CommonMark\Extension\SmartPunct\SmartPunctExtension; +use League\CommonMark\MarkdownConverter; use RuntimeException; /** @@ -473,13 +478,21 @@ class Episode extends Entity public function setDescriptionMarkdown(string $descriptionMarkdown): static { - $converter = new CommonMarkConverter([ - 'html_input' => 'strip', + $config = [ + 'html_input' => 'escape', 'allow_unsafe_links' => false, - ]); + ]; + + $environment = new Environment($config); + $environment->addExtension(new CommonMarkCoreExtension()); + $environment->addExtension(new AutolinkExtension()); + $environment->addExtension(new SmartPunctExtension()); + $environment->addExtension(new DisallowedRawHtmlExtension()); + + $converter = new MarkdownConverter($environment); $this->attributes['description_markdown'] = $descriptionMarkdown; - $this->attributes['description_html'] = $converter->convertToHtml($descriptionMarkdown); + $this->attributes['description_html'] = $converter->convert($descriptionMarkdown); return $this; } diff --git a/app/Entities/Page.php b/app/Entities/Page.php index 7cf868a010f4d022b9b8d854120861bb5cadc96f..1628a787b3938c00bb116e7b22eeea19398da227 100644 --- a/app/Entities/Page.php +++ b/app/Entities/Page.php @@ -12,7 +12,12 @@ namespace App\Entities; use CodeIgniter\Entity\Entity; use CodeIgniter\I18n\Time; -use League\CommonMark\CommonMarkConverter; +use League\CommonMark\Environment\Environment; +use League\CommonMark\Extension\Autolink\AutolinkExtension; +use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension; +use League\CommonMark\Extension\DisallowedRawHtml\DisallowedRawHtmlExtension; +use League\CommonMark\Extension\SmartPunct\SmartPunctExtension; +use League\CommonMark\MarkdownConverter; /** * @property int $id @@ -49,13 +54,20 @@ class Page extends Entity public function setContentMarkdown(string $contentMarkdown): static { - $converter = new CommonMarkConverter([ - 'html_input' => 'strip', + $config = [ 'allow_unsafe_links' => false, - ]); + ]; + + $environment = new Environment($config); + $environment->addExtension(new CommonMarkCoreExtension()); + $environment->addExtension(new AutolinkExtension()); + $environment->addExtension(new SmartPunctExtension()); + $environment->addExtension(new DisallowedRawHtmlExtension()); + + $converter = new MarkdownConverter($environment); $this->attributes['content_markdown'] = $contentMarkdown; - $this->attributes['content_html'] = $converter->convertToHtml($contentMarkdown); + $this->attributes['content_html'] = $converter->convert($contentMarkdown); return $this; } diff --git a/app/Entities/Podcast.php b/app/Entities/Podcast.php index 55a2ec3c0cb955199ac3fa4c7d95cf39c2c09f52..28a1e3fe5cdcd335e4721f805655e4d7eba821e3 100644 --- a/app/Entities/Podcast.php +++ b/app/Entities/Podcast.php @@ -23,7 +23,12 @@ use CodeIgniter\Entity\Entity; use CodeIgniter\Files\File; use CodeIgniter\HTTP\Files\UploadedFile; use CodeIgniter\I18n\Time; -use League\CommonMark\CommonMarkConverter; +use League\CommonMark\Environment\Environment; +use League\CommonMark\Extension\Autolink\AutolinkExtension; +use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension; +use League\CommonMark\Extension\DisallowedRawHtml\DisallowedRawHtmlExtension; +use League\CommonMark\Extension\SmartPunct\SmartPunctExtension; +use League\CommonMark\MarkdownConverter; use Modules\Auth\Entities\User; use RuntimeException; @@ -375,13 +380,21 @@ class Podcast extends Entity public function setDescriptionMarkdown(string $descriptionMarkdown): static { - $converter = new CommonMarkConverter([ - 'html_input' => 'strip', + $config = [ + 'html_input' => 'escape', 'allow_unsafe_links' => false, - ]); + ]; + + $environment = new Environment($config); + $environment->addExtension(new CommonMarkCoreExtension()); + $environment->addExtension(new AutolinkExtension()); + $environment->addExtension(new SmartPunctExtension()); + $environment->addExtension(new DisallowedRawHtmlExtension()); + + $converter = new MarkdownConverter($environment); $this->attributes['description_markdown'] = $descriptionMarkdown; - $this->attributes['description_html'] = $converter->convertToHtml($descriptionMarkdown); + $this->attributes['description_html'] = $converter->convert($descriptionMarkdown); return $this; } @@ -399,17 +412,25 @@ class Podcast extends Entity return $this; } - $converter = new CommonMarkConverter([ - 'html_input' => 'strip', + $config = [ + 'html_input' => 'escape', 'allow_unsafe_links' => false, - ]); + ]; + + $environment = new Environment($config); + $environment->addExtension(new CommonMarkCoreExtension()); + $environment->addExtension(new AutolinkExtension()); + $environment->addExtension(new SmartPunctExtension()); + $environment->addExtension(new DisallowedRawHtmlExtension()); + + $converter = new MarkdownConverter($environment); $this->attributes[ 'episode_description_footer_markdown' ] = $episodeDescriptionFooterMarkdown; $this->attributes[ 'episode_description_footer_html' - ] = $converter->convertToHtml($episodeDescriptionFooterMarkdown); + ] = $converter->convert($episodeDescriptionFooterMarkdown); return $this; } diff --git a/app/Helpers/form_helper.php b/app/Helpers/form_helper.php new file mode 100644 index 0000000000000000000000000000000000000000..aedc6db3dbb354909fc6708353ad3e6df11f056e --- /dev/null +++ b/app/Helpers/form_helper.php @@ -0,0 +1,45 @@ +<?php + +declare(strict_types=1); + +if (! function_exists('form_markdown_textarea')) { + /** + * Textarea field + * + * @param mixed $data + * @param mixed $extra + */ + function form_markdown_textarea($data = '', string $value = '', $extra = ''): string + { + $defaults = [ + 'name' => is_array($data) ? '' : $data, + 'cols' => '40', + 'rows' => '10', + ]; + if (! is_array($data) || ! isset($data['value'])) { + $val = $value; + } else { + $val = $data['value']; + unset($data['value']); // textareas don't use the value attribute + } + + // Unsets default rows and cols if defined in extra field as array or string. + if ((is_array($extra) && array_key_exists('rows', $extra)) || (is_string($extra) && stripos( + preg_replace('~\s+~', '', $extra), + 'rows=' + ) !== false)) { + unset($defaults['rows']); + } + + if ((is_array($extra) && array_key_exists('cols', $extra)) || (is_string($extra) && stripos( + preg_replace('~\s+~', '', $extra), + 'cols=' + ) !== false)) { + unset($defaults['cols']); + } + + return '<textarea ' . rtrim(parse_form_attributes($data, $defaults)) . stringify_attributes($extra) . '>' + . $val + . "</textarea>\n"; + } +} diff --git a/app/Views/Components/Forms/MarkdownEditor.php b/app/Views/Components/Forms/MarkdownEditor.php index 9fab63a06a629236e6b1c45dd9ca676d75632725..66fb54c277fed2fab1b9d4d9992e44040df306de 100644 --- a/app/Views/Components/Forms/MarkdownEditor.php +++ b/app/Views/Components/Forms/MarkdownEditor.php @@ -6,6 +6,16 @@ namespace App\Views\Components\Forms; class MarkdownEditor extends FormComponent { + /** + * @var string[] + */ + protected array $disallowList = []; + + public function setDisallowList(string $value): void + { + $this->disallowList = explode(',', $value); + } + public function render(): string { $editorClass = 'w-full flex flex-col bg-elevated border-3 border-contrast rounded-lg overflow-hidden focus-within:ring-accent ' . $this->class; @@ -13,30 +23,83 @@ class MarkdownEditor extends FormComponent $this->attributes['class'] = 'bg-elevated border-none focus:border-none focus:outline-none focus:ring-0 w-full h-full'; $this->attributes['rows'] = 6; - // dd(htmlspecialchars_decode($this->value)); $value = htmlspecialchars_decode($this->value); - $textarea = form_textarea($this->attributes, old($this->name, $value, false)); - $icons = [ - 'heading' => icon('heading'), - 'bold' => icon('bold'), - 'italic' => icon('italic'), - 'list-unordered' => icon('list-unordered'), - 'list-ordered' => icon('list-ordered'), - 'quote' => icon('quote'), - 'link' => icon('link'), - 'image-add' => icon('image-add'), - 'markdown' => icon( - 'markdown', - 'mr-1 text-lg opacity-40' - ), - ]; + $oldValue = old($this->name); + if ($oldValue === null) { + $oldValue = $value; + } + $textarea = form_textarea($this->attributes, $oldValue); + $markdownIcon = icon( + 'markdown', + 'mr-1 text-lg opacity-40' + ); $translations = [ 'write' => lang('Common.forms.editor.write'), 'preview' => lang('Common.forms.editor.preview'), 'help' => lang('Common.forms.editor.help'), ]; + $toolbarGroups = [ + [ + [ + 'name' => 'header', + 'tag' => 'md-header', + 'icon' => icon('heading'), + ], + [ + 'name' => 'bold', + 'tag' => 'md-bold', + 'icon' => icon('bold'), + ], + [ + 'name' => 'italic', + 'tag' => 'md-italic', + 'icon' => icon('italic'), + ], + ], + [ + [ + 'name' => 'unordered-list', + 'tag' => 'md-unordered-list', + 'icon' => icon('list-unordered'), + ], + [ + 'name' => 'ordered-list', + 'tag' => 'md-ordered-list ', + 'icon' => icon('list-ordered'), + ], + ], + [ + [ + 'name' => 'quote', + 'tag' => 'md-quote', + 'icon' => icon('quote'), + ], + [ + 'name' => 'link', + 'tag' => 'md-link', + 'icon' => icon('link'), + ], + [ + 'name' => 'image', + 'tag' => 'md-image', + 'icon' => icon('image-add'), + ], + ], + ]; + + $toolbarContent = ''; + foreach ($toolbarGroups as $buttonsGroup) { + $toolbarContent .= '<div class="inline-flex text-2xl gap-x-1">'; + foreach ($buttonsGroup as $button) { + if (! in_array($button['name'], $this->disallowList, true)) { + $toolbarContent .= '<' . $button['tag'] . ' class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100">' . $button['icon'] . '</' . $button['tag'] . '>'; + } + } + $toolbarContent .= '</div>'; + } + return <<<HTML <div class="{$editorClass}"> <header class="px-2"> @@ -45,22 +108,7 @@ class MarkdownEditor extends FormComponent <button type="button" slot="write" class="px-2 font-semibold focus:ring-inset focus:ring-accent">{$translations['write']}</button> <button type="button" slot="preview" class="px-2 font-semibold focus:ring-inset focus:ring-accent">{$translations['preview']}</button> </markdown-write-preview> - <markdown-toolbar for="{$this->id}" class="flex gap-4 px-2 py-1"> - <div class="inline-flex text-2xl gap-x-1"> - <md-header class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100">{$icons['heading']}</md-header> - <md-bold class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100" data-hotkey-scope="{$this->id}" data-hotkey="Control+b,Meta+b">{$icons['bold']}</md-bold> - <md-italic class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100" data-hotkey-scope="{$this->id}" data-hotkey="Control+i,Meta+i">{$icons['italic']}</md-italic> - </div> - <div class="inline-flex text-2xl gap-x-1"> - <md-unordered-list class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100">{$icons['list-unordered']}</md-unordered-list> - <md-ordered-list class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100">{$icons['list-ordered']}</md-ordered-list> - </div> - <div class="inline-flex text-2xl gap-x-1"> - <md-quote class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100">{$icons['quote']}</md-quote> - <md-link class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100" data-hotkey-scope="{$this->id}" data-hotkey="Control+k,Meta+k">{$icons['link']}</md-link> - <md-image class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100">{$icons['image-add']}</md-image> - </div> - </markdown-toolbar> + <markdown-toolbar for="{$this->id}" class="flex gap-4 px-2 py-1">{$toolbarContent}</markdown-toolbar> </div> </header> <div class="relative"> @@ -68,7 +116,7 @@ class MarkdownEditor extends FormComponent <markdown-preview for="{$this->id}" class="absolute top-0 left-0 hidden w-full h-full max-w-full px-3 py-2 overflow-y-auto prose bg-base" showClass="bg-elevated" /> </div> <footer class="flex px-2 py-1 border-t bg-base"> - <a href="https://commonmark.org/help/" class="inline-flex items-center text-xs font-semibold text-skin-muted hover:text-skin-base" target="_blank" rel="noopener noreferrer">{$icons['markdown']}{$translations['help']}</a> + <a href="https://commonmark.org/help/" class="inline-flex items-center text-xs font-semibold text-skin-muted hover:text-skin-base" target="_blank" rel="noopener noreferrer">{$markdownIcon}{$translations['help']}</a> </footer> </div> HTML; diff --git a/composer.json b/composer.json index 634f87c00064bbee523feab2d799d6f82b52dac3..e3d8559082fd80cd5c7aecab9958e938a6c43575 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "geoip2/geoip2": "^v2.11.0", "myth/auth": "dev-develop", "codeigniter4/codeigniter4": "dev-develop", - "league/commonmark": "^v1.6.6", + "league/commonmark": "^2.2", "vlucas/phpdotenv": "^v5.3.0", "league/html-to-markdown": "^v5.0.1", "opawg/user-agents-php": "^v1.0", diff --git a/composer.lock b/composer.lock index d55a4c9d0e06ef1990223e5ba130fe1433b52a92..91ca6af6afe3cffe1531fca3f0fbf3ef361b9db0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1cd09e20009835bd1480554991ad2ff1", + "content-hash": "bf66875f72680d0f5953f03bf31c8612", "packages": [ { "name": "brick/math", @@ -307,6 +307,74 @@ ], "time": "2021-06-07T13:58:28+00:00" }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "0992cc19268b259a39e86f296da5f0677841f42c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/0992cc19268b259a39e86f296da5f0677841f42c", + "reference": "0992cc19268b259a39e86f296da5f0677841f42c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^3.14" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["MIT"], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": ["access", "data", "dot", "notation"], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.1" + }, + "time": "2021-08-13T13:06:58+00:00" + }, { "name": "essence/dom", "version": "1.0.0", @@ -783,40 +851,52 @@ }, { "name": "league/commonmark", - "version": "1.6.6", + "version": "2.2.1", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "c4228d11e30d7493c6836d20872f9582d8ba6dcf" + "reference": "f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/c4228d11e30d7493c6836d20872f9582d8ba6dcf", - "reference": "c4228d11e30d7493c6836d20872f9582d8ba6dcf", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a", + "reference": "f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": "^7.1 || ^8.0" - }, - "conflict": { - "scrutinizer/ocular": "1.7.*" + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.15" }, "require-dev": { - "cebe/markdown": "~1.0", - "commonmark/commonmark.js": "0.29.2", - "erusev/parsedown": "~1.0", + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.30.0", + "commonmark/commonmark.js": "0.30.0", + "composer/package-versions-deprecated": "^1.8", + "erusev/parsedown": "^1.0", "ext-json": "*", "github/gfm": "0.29.0", - "michelf/php-markdown": "~1.4", - "mikehaertl/php-shellcommand": "^1.4", - "phpstan/phpstan": "^0.12.90", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.2", - "scrutinizer/ocular": "^1.5", - "symfony/finder": "^4.2" + "michelf/php-markdown": "^1.4", + "phpstan/phpstan": "^0.12.88 || ^1.0.0", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" }, - "bin": ["bin/commonmark"], "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.3-dev" + } + }, "autoload": { "psr-4": { "League\\CommonMark\\": "src" @@ -832,7 +912,7 @@ "role": "Lead Developer" } ], - "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and Github-Flavored Markdown (GFM)", + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", "homepage": "https://commonmark.thephpleague.com", "keywords": [ "commonmark", @@ -846,15 +926,12 @@ ], "support": { "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", "issues": "https://github.com/thephpleague/commonmark/issues", "rss": "https://github.com/thephpleague/commonmark/releases.atom", "source": "https://github.com/thephpleague/commonmark" }, "funding": [ - { - "url": "https://enjoy.gitstore.app/repositories/thephpleague/commonmark", - "type": "custom" - }, { "url": "https://www.colinodell.com/sponsor", "type": "custom" @@ -867,16 +944,92 @@ "url": "https://github.com/colinodell", "type": "github" }, - { - "url": "https://www.patreon.com/colinodell", - "type": "patreon" - }, { "url": "https://tidelift.com/funding/github/packagist/league/commonmark", "type": "tidelift" } ], - "time": "2021-07-17T17:13:23+00:00" + "time": "2022-01-25T14:37:33+00:00" + }, + { + "name": "league/config", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.90", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2021-08-14T12:15:32+00:00" }, { "name": "league/html-to-markdown", @@ -1236,6 +1389,138 @@ ], "time": "2021-06-10T04:25:01+00:00" }, + { + "name": "nette/schema", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/9a39cef03a5b34c7de64f551538cbba05c2be5df", + "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df", + "shasum": "" + }, + "require": { + "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0", + "php": ">=7.1 <8.2" + }, + "require-dev": { + "nette/tester": "^2.3 || ^2.4", + "phpstan/phpstan-nette": "^0.12", + "tracy/tracy": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause", "GPL-2.0-only", "GPL-3.0-only"], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📠Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": ["config", "nette"], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.2.2" + }, + "time": "2021-10-15T11:40:02+00:00" + }, + { + "name": "nette/utils", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "967cfc4f9a1acd5f1058d76715a424c53343c20c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/967cfc4f9a1acd5f1058d76715a424c53343c20c", + "reference": "967cfc4f9a1acd5f1058d76715a424c53343c20c", + "shasum": "" + }, + "require": { + "php": ">=7.2 <8.1" + }, + "conflict": { + "nette/di": "<3.0.6" + }, + "require-dev": { + "nette/tester": "~2.0", + "phpstan/phpstan": "^0.12", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause", "GPL-2.0-only", "GPL-3.0-only"], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v3.2.2" + }, + "time": "2021-03-03T22:53:25+00:00" + }, { "name": "opawg/user-agents-php", "version": "v1.0", @@ -1541,9 +1826,53 @@ "description": "Common interface for caching libraries", "keywords": ["cache", "psr", "psr-6"], "support": { - "source": "https://github.com/php-fig/cache/tree/master" + "source": "https://github.com/php-fig/cache/tree/master" + }, + "time": "2016-08-06T20:24:11+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["MIT"], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": ["events", "psr", "psr-14"], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" }, - "time": "2016-08-06T20:24:11+00:00" + "time": "2019-01-08T18:20:26+00:00" }, { "name": "psr/log", @@ -1741,6 +2070,69 @@ ], "time": "2020-08-18T17:17:46+00:00" }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627", + "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": ["function.php"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["MIT"], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-23T23:28:01+00:00" + }, { "name": "symfony/polyfill-ctype", "version": "v1.23.0", @@ -2787,85 +3179,6 @@ }, "time": "2021-02-28T12:30:32+00:00" }, - { - "name": "nette/utils", - "version": "v3.2.2", - "source": { - "type": "git", - "url": "https://github.com/nette/utils.git", - "reference": "967cfc4f9a1acd5f1058d76715a424c53343c20c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/967cfc4f9a1acd5f1058d76715a424c53343c20c", - "reference": "967cfc4f9a1acd5f1058d76715a424c53343c20c", - "shasum": "" - }, - "require": { - "php": ">=7.2 <8.1" - }, - "conflict": { - "nette/di": "<3.0.6" - }, - "require-dev": { - "nette/tester": "~2.0", - "phpstan/phpstan": "^0.12", - "tracy/tracy": "^2.3" - }, - "suggest": { - "ext-gd": "to use Image", - "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", - "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", - "ext-json": "to use Nette\\Utils\\Json", - "ext-mbstring": "to use Strings::lower() etc...", - "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", - "ext-xml": "to use Strings::length() etc. when mbstring is not available" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-dev" - } - }, - "autoload": { - "classmap": ["src/"] - }, - "notification-url": "https://packagist.org/downloads/", - "license": ["BSD-3-Clause", "GPL-2.0-only", "GPL-3.0-only"], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🛠Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", - "homepage": "https://nette.org", - "keywords": [ - "array", - "core", - "datetime", - "images", - "json", - "nette", - "paginator", - "password", - "slugify", - "string", - "unicode", - "utf-8", - "utility", - "validation" - ], - "support": { - "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v3.2.2" - }, - "time": "2021-03-03T22:53:25+00:00" - }, { "name": "nikic/php-parser", "version": "v4.10.5", @@ -3838,50 +4151,6 @@ }, "time": "2021-03-05T17:36:06+00:00" }, - { - "name": "psr/event-dispatcher", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", - "shasum": "" - }, - "require": { - "php": ">=7.2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\EventDispatcher\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": ["MIT"], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Standard interfaces for event handling.", - "keywords": ["events", "psr", "psr-14"], - "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" - }, - "time": "2019-01-08T18:20:26+00:00" - }, { "name": "rector/rector", "version": "0.11.16", @@ -5271,69 +5540,6 @@ ], "time": "2021-05-26T17:57:12+00:00" }, - { - "name": "symfony/deprecation-contracts", - "version": "v2.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": ["function.php"] - }, - "notification-url": "https://packagist.org/downloads/", - "license": ["MIT"], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-03-23T23:28:01+00:00" - }, { "name": "symfony/error-handler", "version": "v5.3.0", diff --git a/themes/cp_admin/episode/create.php b/themes/cp_admin/episode/create.php index bfc2d6115b2960c9ee561c70385eca2629553944..4bb1b89c23a16ec2e63de567f978d2692d0da80c 100644 --- a/themes/cp_admin/episode/create.php +++ b/themes/cp_admin/episode/create.php @@ -118,13 +118,15 @@ as="MarkdownEditor" name="description" label="<?= lang('Episode.form.description') ?>" - required="true" /> + required="true" + disallowList="header,quote" /> <Forms.Field as="MarkdownEditor" name="description_footer" label="<?= lang('Episode.form.description_footer') ?>" - hint="<?= lang('Episode.form.description_footer_hint') ?>" /> + hint="<?= lang('Episode.form.description_footer_hint') ?>" + disallowList="header,quote" /> </Forms.Section> diff --git a/themes/cp_admin/episode/edit.php b/themes/cp_admin/episode/edit.php index 8f2cbb19b00c19e9b2991eca9a146bd058041516..2ea9988d64a4164e6cf73e3bba859c6a6b832712 100644 --- a/themes/cp_admin/episode/edit.php +++ b/themes/cp_admin/episode/edit.php @@ -123,14 +123,16 @@ name="description" label="<?= lang('Episode.form.description') ?>" value="<?= htmlspecialchars($episode->description_markdown) ?>" - required="true" /> + required="true" + disallowList="header,quote" /> <Forms.Field as="MarkdownEditor" name="description_footer" label="<?= lang('Episode.form.description_footer') ?>" hint="<?= lang('Episode.form.description_footer_hint') ?>" - value="<?= htmlspecialchars($podcast->episode_description_footer_markdown) ?? '' ?>" /> + value="<?= htmlspecialchars($podcast->episode_description_footer_markdown) ?? '' ?>" + disallowList="header,quote" /> </Forms.Section> diff --git a/themes/cp_admin/podcast/create.php b/themes/cp_admin/podcast/create.php index f42576cbefbcc2db4c5e07a5d8e15e8c6a06c0e9..3d4250e3fc514b0e162e74fcdb3fde426b602200 100644 --- a/themes/cp_admin/podcast/create.php +++ b/themes/cp_admin/podcast/create.php @@ -53,7 +53,8 @@ as="MarkdownEditor" name="description" label="<?= lang('Podcast.form.description') ?>" - required="true" /> + required="true" + disallowList="header,quote" /> <fieldset> <legend><?= lang('Podcast.form.type.label') ?></legend> diff --git a/themes/cp_admin/podcast/edit.php b/themes/cp_admin/podcast/edit.php index a895d19ccdd2bacf18bc17a840d73ad63760885e..2f6de9d2b9fb7c017ad17aad3ff939ba41fc1295 100644 --- a/themes/cp_admin/podcast/edit.php +++ b/themes/cp_admin/podcast/edit.php @@ -68,7 +68,8 @@ name="description" label="<?= lang('Podcast.form.description') ?>" value="<?= htmlspecialchars($podcast->description_markdown) ?>" - required="true" /> + required="true" + disallowList="header,quote" /> <fieldset> <legend><?= lang('Podcast.form.type.label') ?></legend>