)?\\[${shortcode.name}(?(=| +)[^\\]]*)?\\](<\\/p>)?(?(((?!(${openingRegexp}|(\\[\\/${shortcode.name}\\]))).)|\\n)*)\\[\\/${shortcode.name}\\](?<\\/p>)?`;
17 |
18 | output = output.replace(new RegExp(regexp, 'g'), (...matches) => {
19 | shortcodeCounter += 1;
20 |
21 | const groups = matches.pop();
22 |
23 | let content = shortcode.type === 'block'
24 | ? groups.content.replace(/$/, '')
25 | : groups.content;
26 |
27 | const bbcode = Object.keys(shortcode.attributes).reduce((acc, attrName) => acc || (shortcode.attributes[attrName].bbcode && shortcode.attributes[attrName].shorthand && attrName), '');
28 | const innerHTMLAttribute = Object.keys(shortcode.attributes).reduce((acc, attrName) => acc || (shortcode.attributes[attrName].innerHTML && attrName), '');
29 |
30 | let attrGroup = bbcode && groups.attributes && groups.attributes.startsWith('=')
31 | ? `${bbcode}${groups.attributes}`
32 | : groups.attributes || '';
33 |
34 | if (innerHTMLAttribute) {
35 | const innerHTML = shortcode.type === 'block'
36 | ? content.replace(/^
/, '').replace(/<\/p>$/, '').replace(/^ $/, '')
37 | : content.replace(/^ $/, '');
38 |
39 | attrGroup = attrGroup
40 | ? `${attrGroup} ${innerHTMLAttribute}="${innerHTML}"`
41 | : `${innerHTMLAttribute}="${innerHTML}"`;
42 |
43 | content = '';
44 | }
45 |
46 | const domAttributes = new DOMParser().parseFromString(`
`, 'text/html').body.firstChild.attributes;
47 |
48 | const attributes = Object.keys(shortcode.attributes).reduce((acc, attrName) => {
49 | const attribute = shortcode.attributes[attrName];
50 |
51 | let attrValue = domAttributes.getNamedItem(attrName)
52 | ? domAttributes.getNamedItem(attrName).value
53 | : attribute.default.value;
54 |
55 | if (attribute.type === Boolean && domAttributes.getNamedItem(attrName)) {
56 | attrValue = domAttributes.getNamedItem(attrName) !== 'false';
57 | }
58 |
59 | if (attribute.type === Number) {
60 | attrValue = +attrValue;
61 | }
62 |
63 | acc[attrName] = attrValue;
64 |
65 | return acc;
66 | }, {});
67 |
68 | let replacement = '';
69 |
70 | const attributesEncoded = encodeURIComponent(JSON.stringify(attributes));
71 |
72 | if (shortcode.type === 'block') {
73 | replacement += ``;
74 | replacement += content;
75 | replacement += '';
76 | }
77 |
78 | if (shortcode.type === 'inline') {
79 | replacement += groups.p1 || '';
80 | replacement += ``;
81 | replacement += content;
82 | replacement += '';
83 | replacement += groups.p2 || '';
84 | }
85 |
86 | return replacement;
87 | });
88 | });
89 | }
90 |
91 | output = uncollapse(output);
92 |
93 | return output;
94 | },
95 | });
96 |
--------------------------------------------------------------------------------
/nextgen-editor/src/save.js:
--------------------------------------------------------------------------------
1 | import collapse from './collapse';
2 |
3 | window.nextgenEditor.addHook('hookHTMLtoMarkdown', {
4 | weight: -50,
5 | handler(options, editor, input) {
6 | let output = input;
7 |
8 | output = collapse(output);
9 |
10 | const domOutput = new DOMParser().parseFromString(output, 'text/html');
11 |
12 | let domShortcode = domOutput.querySelector('shortcode-block, shortcode-inline');
13 |
14 | while (domShortcode) {
15 | const name = domShortcode.getAttribute('name');
16 | const shortcode = window.nextgenEditor.shortcodes[name];
17 | const attributes = JSON.parse(decodeURIComponent(domShortcode.getAttribute('attributes')));
18 |
19 | const innerHTMLAttribute = Object.keys(shortcode.attributes).reduce((acc, attrName) => acc || (shortcode.attributes[attrName].innerHTML && attrName), '');
20 |
21 | const attrLine = Object.keys(shortcode.attributes).reduce((acc, attrName) => {
22 | const attribute = shortcode.attributes[attrName];
23 |
24 | if (attribute.type === Boolean) {
25 | return attributes[attrName]
26 | ? `${acc} ${attrName}`
27 | : acc;
28 | }
29 |
30 | if (attributes[attrName] === attribute.default.value && !attribute.default.preserve) {
31 | return acc;
32 | }
33 |
34 | if (attribute.bbcode && attribute.shorthand) {
35 | return `="${attributes[attrName]}"${acc}`;
36 | }
37 |
38 | if (attribute.innerHTML) {
39 | return acc;
40 | }
41 |
42 | return `${acc} ${attrName}="${attributes[attrName]}"`;
43 | }, '');
44 |
45 | if (shortcode.type === 'block') {
46 | if (domShortcode.innerHTML === '
') {
47 | domShortcode.innerHTML = '';
48 | }
49 |
50 | if (innerHTMLAttribute) {
51 | domShortcode.outerHTML = `[${shortcode.realName}${attrLine}]${attributes[innerHTMLAttribute]}[/${shortcode.realName}]
`;
52 | } else if (domShortcode.innerHTML) {
53 | domShortcode.outerHTML = `[${shortcode.realName}${attrLine}]
${domShortcode.innerHTML}[/${shortcode.realName}]
`;
54 | } else {
55 | domShortcode.outerHTML = `[${shortcode.realName}${attrLine} /]
`;
56 | }
57 | }
58 |
59 | if (shortcode.type === 'inline') {
60 | if (domShortcode.innerHTML === ' ') {
61 | domShortcode.innerHTML = '';
62 | }
63 |
64 | if (innerHTMLAttribute) {
65 | domShortcode.outerHTML = `[${shortcode.realName}${attrLine}]${attributes[innerHTMLAttribute]}[/${shortcode.realName}]`;
66 | } else if (domShortcode.innerHTML) {
67 | domShortcode.outerHTML = `[${shortcode.realName}${attrLine}]${domShortcode.innerHTML}[/${shortcode.realName}]`;
68 | } else {
69 | domShortcode.outerHTML = `[${shortcode.realName}${attrLine} /]`;
70 | }
71 | }
72 |
73 | domShortcode = domOutput.querySelector('shortcode-block, shortcode-inline');
74 | }
75 |
76 | output = domOutput.body.innerHTML;
77 |
78 | return output;
79 | },
80 | });
81 |
--------------------------------------------------------------------------------
/nextgen-editor/vue.config.js:
--------------------------------------------------------------------------------
1 | const DirectoryNamedWebpackPlugin = require('directory-named-webpack-plugin');
2 |
3 | module.exports = {
4 | filenameHashing: false,
5 | publicPath: process.env.NODE_ENV === 'development'
6 | ? `http://${process.env.DEV_HOST}:${process.env.DEV_PORT}/`
7 | : '/',
8 | configureWebpack: {
9 | resolve: {
10 | plugins: [
11 | new DirectoryNamedWebpackPlugin(),
12 | ],
13 | },
14 | optimization: {
15 | splitChunks: false,
16 | },
17 | },
18 | chainWebpack: (webpackConfig) => {
19 | webpackConfig.plugins.delete('html');
20 | webpackConfig.plugins.delete('preload');
21 | webpackConfig.plugins.delete('prefetch');
22 | },
23 | devServer: {
24 | host: process.env.DEV_HOST,
25 | port: process.env.DEV_PORT,
26 | disableHostCheck: true,
27 | headers: {
28 | 'Access-Control-Allow-Origin': '*',
29 | },
30 | },
31 | };
32 |
--------------------------------------------------------------------------------
/shortcode-core.yaml:
--------------------------------------------------------------------------------
1 | enabled: true
2 | active: true
3 | active_admin: true
4 | admin_pages_only: true
5 | parser: regular
6 | include_default_shortcodes: true
7 | css:
8 | notice_enabled: true
9 | custom_shortcodes:
10 | fontawesome:
11 | load: true
12 | url: '//maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css'
13 | v5: false
14 | nextgen-editor:
15 | env: production
16 | dev_host: localhost
17 | dev_port: 2001
18 |
--------------------------------------------------------------------------------
/templates/shortcodes/notice.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
{{ content|raw }}
3 |
--------------------------------------------------------------------------------
/vendor/autoload.php:
--------------------------------------------------------------------------------
1 | $vendorDir . '/composer/InstalledVersions.php',
10 | 'Grav\\Plugin\\ShortcodeCorePlugin' => $baseDir . '/shortcode-core.php',
11 | );
12 |
--------------------------------------------------------------------------------
/vendor/composer/autoload_namespaces.php:
--------------------------------------------------------------------------------
1 | array($vendorDir . '/thunderer/shortcode/src'),
10 | 'Grav\\Plugin\\Shortcodes\\' => array($baseDir . '/classes/shortcodes'),
11 | 'Grav\\Plugin\\ShortcodeCore\\' => array($baseDir . '/classes/plugin'),
12 | );
13 |
--------------------------------------------------------------------------------
/vendor/composer/autoload_real.php:
--------------------------------------------------------------------------------
1 | register(true);
35 |
36 | return $loader;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/vendor/composer/autoload_static.php:
--------------------------------------------------------------------------------
1 |
11 | array (
12 | 'Thunder\\Shortcode\\' => 18,
13 | ),
14 | 'G' =>
15 | array (
16 | 'Grav\\Plugin\\Shortcodes\\' => 23,
17 | 'Grav\\Plugin\\ShortcodeCore\\' => 26,
18 | ),
19 | );
20 |
21 | public static $prefixDirsPsr4 = array (
22 | 'Thunder\\Shortcode\\' =>
23 | array (
24 | 0 => __DIR__ . '/..' . '/thunderer/shortcode/src',
25 | ),
26 | 'Grav\\Plugin\\Shortcodes\\' =>
27 | array (
28 | 0 => __DIR__ . '/../..' . '/classes/shortcodes',
29 | ),
30 | 'Grav\\Plugin\\ShortcodeCore\\' =>
31 | array (
32 | 0 => __DIR__ . '/../..' . '/classes/plugin',
33 | ),
34 | );
35 |
36 | public static $classMap = array (
37 | 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
38 | 'Grav\\Plugin\\ShortcodeCorePlugin' => __DIR__ . '/../..' . '/shortcode-core.php',
39 | );
40 |
41 | public static function getInitializer(ClassLoader $loader)
42 | {
43 | return \Closure::bind(function () use ($loader) {
44 | $loader->prefixLengthsPsr4 = ComposerStaticInit20dff4ef15e2090e54c04a9aa83321b9::$prefixLengthsPsr4;
45 | $loader->prefixDirsPsr4 = ComposerStaticInit20dff4ef15e2090e54c04a9aa83321b9::$prefixDirsPsr4;
46 | $loader->classMap = ComposerStaticInit20dff4ef15e2090e54c04a9aa83321b9::$classMap;
47 |
48 | }, null, ClassLoader::class);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/vendor/composer/installed.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": [
3 | {
4 | "name": "thunderer/shortcode",
5 | "version": "v0.7.6",
6 | "version_normalized": "0.7.6.0",
7 | "source": {
8 | "type": "git",
9 | "url": "https://github.com/thunderer/Shortcode.git",
10 | "reference": "9f81424b4909007483d93c5defc0917d8a58debd"
11 | },
12 | "dist": {
13 | "type": "zip",
14 | "url": "https://api.github.com/repos/thunderer/Shortcode/zipball/9f81424b4909007483d93c5defc0917d8a58debd",
15 | "reference": "9f81424b4909007483d93c5defc0917d8a58debd",
16 | "shasum": ""
17 | },
18 | "require": {
19 | "php": ">=5.3"
20 | },
21 | "require-dev": {
22 | "phpunit/phpunit": ">=4.1",
23 | "symfony/yaml": ">=2.0"
24 | },
25 | "suggest": {
26 | "ext-dom": "if you want to use XML serializer",
27 | "ext-json": "if you want to use JSON serializer",
28 | "symfony/yaml": "if you want to use YAML serializer"
29 | },
30 | "time": "2024-12-15T21:57:40+00:00",
31 | "type": "library",
32 | "installation-source": "dist",
33 | "autoload": {
34 | "psr-4": {
35 | "Thunder\\Shortcode\\": "src/"
36 | }
37 | },
38 | "notification-url": "https://packagist.org/downloads/",
39 | "license": [
40 | "MIT"
41 | ],
42 | "authors": [
43 | {
44 | "name": "Tomasz Kowalczyk",
45 | "email": "tomasz@kowalczyk.cc"
46 | }
47 | ],
48 | "description": "Advanced shortcode (BBCode) parser and engine for PHP",
49 | "keywords": [
50 | "bbcode",
51 | "engine",
52 | "library",
53 | "parser",
54 | "shortcode"
55 | ],
56 | "support": {
57 | "issues": "https://github.com/thunderer/Shortcode/issues",
58 | "source": "https://github.com/thunderer/Shortcode/tree/v0.7.6"
59 | },
60 | "install-path": "../thunderer/shortcode"
61 | }
62 | ],
63 | "dev": true,
64 | "dev-package-names": []
65 | }
66 |
--------------------------------------------------------------------------------
/vendor/composer/installed.php:
--------------------------------------------------------------------------------
1 | array(
3 | 'name' => 'getgrav/shortcode-core',
4 | 'pretty_version' => 'dev-develop',
5 | 'version' => 'dev-develop',
6 | 'reference' => 'd92a78d8a9dca623ae6beab5614655ae0fb1a463',
7 | 'type' => 'grav-plugin',
8 | 'install_path' => __DIR__ . '/../../',
9 | 'aliases' => array(),
10 | 'dev' => true,
11 | ),
12 | 'versions' => array(
13 | 'getgrav/shortcode-core' => array(
14 | 'pretty_version' => 'dev-develop',
15 | 'version' => 'dev-develop',
16 | 'reference' => 'd92a78d8a9dca623ae6beab5614655ae0fb1a463',
17 | 'type' => 'grav-plugin',
18 | 'install_path' => __DIR__ . '/../../',
19 | 'aliases' => array(),
20 | 'dev_requirement' => false,
21 | ),
22 | 'thunderer/shortcode' => array(
23 | 'pretty_version' => 'v0.7.6',
24 | 'version' => '0.7.6.0',
25 | 'reference' => '9f81424b4909007483d93c5defc0917d8a58debd',
26 | 'type' => 'library',
27 | 'install_path' => __DIR__ . '/../thunderer/shortcode',
28 | 'aliases' => array(),
29 | 'dev_requirement' => false,
30 | ),
31 | ),
32 | );
33 |
--------------------------------------------------------------------------------
/vendor/composer/platform_check.php:
--------------------------------------------------------------------------------
1 | = 70103)) {
8 | $issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.3". You are running ' . PHP_VERSION . '.';
9 | }
10 |
11 | if ($issues) {
12 | if (!headers_sent()) {
13 | header('HTTP/1.1 500 Internal Server Error');
14 | }
15 | if (!ini_get('display_errors')) {
16 | if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
17 | fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
18 | } elseif (!headers_sent()) {
19 | echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
20 | }
21 | }
22 | trigger_error(
23 | 'Composer detected issues in your platform: ' . implode(' ', $issues),
24 | E_USER_ERROR
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/.github/workflows/test-old.yaml:
--------------------------------------------------------------------------------
1 | name: TestOld
2 |
3 | on:
4 | push:
5 | branches: ['master']
6 | pull_request: ~
7 | workflow_dispatch: ~
8 |
9 | jobs:
10 | test:
11 | runs-on: '${{ matrix.os }}'
12 | strategy:
13 | matrix:
14 | php: ['5.3', '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3']
15 | os: ['ubuntu-latest']
16 | steps:
17 | - name: 'Checkout'
18 | uses: 'actions/checkout@v4'
19 | - name: 'Install PHP'
20 | uses: 'shivammathur/setup-php@v2'
21 | with:
22 | php-version: '${{ matrix.php }}'
23 | tools: 'composer:v1'
24 | coverage: 'xdebug'
25 | - name: 'PHP'
26 | run: 'php -v'
27 |
28 | - name: 'Composer'
29 | run: 'composer install'
30 | continue-on-error: '${{ matrix.failure }}'
31 | - name: 'PHPUnit'
32 | run: 'php vendor/bin/phpunit --coverage-text'
33 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/.github/workflows/test.yaml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on:
4 | push:
5 | branches: ['master']
6 | pull_request: ~
7 | workflow_dispatch: ~
8 |
9 | jobs:
10 | test:
11 | runs-on: '${{ matrix.os }}'
12 | strategy:
13 | matrix:
14 | php: ['7.4', '8.0', '8.1', '8.2', '8.3']
15 | os: ['ubuntu-latest']
16 | failure: [false]
17 | include:
18 | - { php: '8.4', os: 'ubuntu-latest', failure: true } # Psalm does not support PHP 8.4 yet
19 | - { php: '8.5', os: 'ubuntu-latest', failure: true } # '8.5' means 'nightly'
20 | steps:
21 | - name: 'Checkout'
22 | uses: 'actions/checkout@v4'
23 | - name: 'Install PHP'
24 | uses: 'shivammathur/setup-php@v2'
25 | with:
26 | php-version: '${{ matrix.php }}'
27 | tools: 'composer:v2'
28 | coverage: 'xdebug'
29 | - name: 'PHP'
30 | run: 'php -v'
31 |
32 | - name: 'Composer'
33 | run: 'composer install'
34 | continue-on-error: '${{ matrix.failure }}'
35 | - name: 'PHPUnit'
36 | run: 'php vendor/bin/phpunit --coverage-text'
37 | continue-on-error: '${{ matrix.failure }}'
38 | - name: 'Psalm'
39 | run: |
40 | composer remove --dev -W 'phpunit/phpunit'
41 | composer require --dev -W 'vimeo/psalm=^5.0' 'nikic/php-parser=^4.0'
42 | php vendor/bin/psalm --shepherd --php-version=${{ matrix.php }}
43 | continue-on-error: '${{ matrix.failure }}'
44 | - name: 'Infection'
45 | run: |
46 | composer remove --dev -W 'vimeo/psalm'
47 | composer require --dev -W phpunit/phpunit infection/infection
48 | php vendor/bin/infection
49 | continue-on-error: '${{ matrix.failure }}'
50 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .phpunit.result.cache
3 | infection.log
4 | vendor
5 | composer.lock
6 | coverage
7 | coverage.xml
8 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015-2025 Tomasz Kowalczyk
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is furnished
8 | to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/Makefile:
--------------------------------------------------------------------------------
1 | PHP_VERSION ?= 8.0
2 | PHP := docker-compose run --rm php-${PHP_VERSION}
3 |
4 | php-version:
5 | ${PHP} php -v
6 | cache-clear:
7 | sudo rm -rfv coverage .phpunit.result.cache infection.log
8 |
9 | docker-build:
10 | docker-compose build
11 |
12 | composer-install:
13 | ${PHP} composer install
14 | composer-self-update:
15 | ${PHP} composer self-update
16 | composer-update:
17 | ${PHP} composer update
18 | composer-require:
19 | ${PHP} composer require ${PACKAGE}
20 | composer-require-dev:
21 | ${PHP} composer require --dev ${PACKAGE}
22 |
23 | test: test-phpunit test-infection qa-psalm
24 | test-phpunit:
25 | ${PHP} php -v
26 | ${PHP} php vendor/bin/phpunit --coverage-text
27 | test-phpunit-local:
28 | php -v
29 | php vendor/bin/phpunit --coverage-text
30 | php vendor/bin/psalm --no-cache
31 | php vendor/bin/infection
32 | test-infection:
33 | ${PHP} php vendor/bin/infection -j2 --min-msi=80
34 |
35 | travis:
36 | # PHP_VERSION=5.3 make travis-job
37 | PHP_VERSION=5.4 make travis-job
38 | PHP_VERSION=5.5 make travis-job
39 | PHP_VERSION=5.6 make travis-job
40 | PHP_VERSION=7.0 make travis-job
41 | PHP_VERSION=7.1 make travis-job
42 | PHP_VERSION=7.2 make travis-job
43 | PHP_VERSION=7.3 make travis-job
44 | PHP_VERSION=7.4 make travis-job
45 | PHP_VERSION=8.0 make travis-job
46 | travis-job:
47 | ${PHP} composer update --no-plugins
48 | ${PHP} php -v
49 | ${PHP} php vendor/bin/phpunit
50 | if ${PHP} php -r 'exit((int)(version_compare(PHP_VERSION, "7.1", ">=") === false));'; then \
51 | ${PHP} composer require --dev vimeo/psalm infection/infection; \
52 | ${PHP} vendor/bin/psalm --threads=1 --no-cache --shepherd --find-unused-psalm-suppress; \
53 | ${PHP} vendor/bin/infection; \
54 | ${PHP} composer remove --dev vimeo/psalm infection/infection; \
55 | fi;
56 |
57 | qa-psalm:
58 | ${PHP} php vendor/bin/psalm --no-cache
59 | qa-psalm-suppressed:
60 | grep -rn psalm-suppress src
61 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "thunderer/shortcode",
3 | "description": "Advanced shortcode (BBCode) parser and engine for PHP",
4 | "keywords": ["shortcode", "bbcode", "parser", "engine", "library"],
5 | "license": "MIT",
6 | "authors": [
7 | {
8 | "name": "Tomasz Kowalczyk",
9 | "email": "tomasz@kowalczyk.cc"
10 | }
11 | ],
12 | "require": {
13 | "php": ">=5.3"
14 | },
15 | "require-dev": {
16 | "phpunit/phpunit": ">=4.1",
17 | "symfony/yaml": ">=2.0"
18 | },
19 | "autoload": {
20 | "psr-4": {
21 | "Thunder\\Shortcode\\": "src/"
22 | }
23 | },
24 | "autoload-dev": {
25 | "psr-4": {
26 | "Thunder\\Shortcode\\Tests\\": "tests/"
27 | }
28 | },
29 | "suggest": {
30 | "symfony/yaml": "if you want to use YAML serializer",
31 | "ext-dom": "if you want to use XML serializer",
32 | "ext-json": "if you want to use JSON serializer"
33 | },
34 | "config": {
35 | "allow-plugins": {
36 | "infection/extension-installer": true
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: '3.4'
2 |
3 | x-php: &php
4 | volumes: ['.:/app', './docker/php/php.ini:/usr/local/etc/php/conf.d/php.ini']
5 | working_dir: '/app'
6 |
7 | services:
8 | # PHP 5.3 contains neither mbstring extension nor docker-php-ext-install script
9 | # Original Dockerfile can be found here https://github.com/docker-library/php/pull/20/files
10 | # Unfortunately it fails to build now because GPG signatures do not exist anymore
11 | # php-5.3: { build: { context: docker/php-5.x, args: { PHP_VERSION: 5.3 } } }
12 | php-5.4: { <<: *php, build: { context: docker/php-5.x, args: { PHP_VERSION: 5.4 } } }
13 | php-5.5: { <<: *php, build: { context: docker/php-5.x, args: { PHP_VERSION: 5.5 } } }
14 | php-5.6: { <<: *php, build: { context: docker/php-5.x, args: { PHP_VERSION: 5.6 } } }
15 | php-7.0: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 7.0 } } }
16 | php-7.1: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 7.1.3 } } }
17 | php-7.2: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 7.2 } } }
18 | php-7.3: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 7.3 } } }
19 | php-7.4: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 7.4 } } }
20 | php-8.0: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 8.0 } } }
21 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/docker/php-5.x/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG PHP_VERSION=7.4
2 | FROM php:$PHP_VERSION
3 |
4 | RUN apt update && apt install -y --force-yes libonig-dev libzip-dev
5 | RUN docker-php-ext-install mbstring zip
6 |
7 | RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
8 | && php -r "if (hash_file('sha384', 'composer-setup.php') === 'c31c1e292ad7be5f49291169c0ac8f683499edddcfd4e42232982d0fd193004208a58ff6f353fde0012d35fdd72bc394') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
9 | && php composer-setup.php \
10 | && php -r "unlink('composer-setup.php');" \
11 | && mv composer.phar /usr/local/bin/composer
12 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/docker/php/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG PHP_VERSION=8.0
2 | FROM php:$PHP_VERSION
3 |
4 | RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
5 | && php -r "if (hash_file('sha384', 'composer-setup.php') === '906a84df04cea2aa72f40b5f787e49f22d4c2f19492ac310e8cba5b96ac8b64115ac402c8cd292b8a03482574915d1a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
6 | && php composer-setup.php \
7 | && php -r "unlink('composer-setup.php');" \
8 | && mv composer.phar /usr/local/bin/composer
9 |
10 | RUN apt update && apt install -y libonig-dev libzip-dev
11 | RUN docker-php-ext-install mbstring zip
12 | RUN pecl install xdebug && docker-php-ext-enable xdebug
13 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/docker/php/php.ini:
--------------------------------------------------------------------------------
1 | xdebug.mode=coverage
2 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/infection.json:
--------------------------------------------------------------------------------
1 | {
2 | "source": {
3 | "directories": ["src"]
4 | },
5 | "logs": {
6 | "text": "infection.log"
7 | },
8 | "timeout": 2,
9 | "mutators": {
10 | "@default": true
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 | src
14 |
15 |
16 |
17 |
18 |
19 | tests
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Event/FilterShortcodesEvent.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | class FilterShortcodesEvent
15 | {
16 | /** @var ProcessedShortcode|null */
17 | private $parent;
18 | /** @var ParsedShortcodeInterface[] */
19 | private $shortcodes = array();
20 |
21 | /**
22 | * @param ParsedShortcodeInterface[] $shortcodes
23 | * @param ProcessedShortcode|null $parent
24 | */
25 | public function __construct(array $shortcodes, $parent = null)
26 | {
27 | if(null !== $parent && false === $parent instanceof ProcessedShortcode) {
28 | throw new \LogicException('Parameter $parent must be an instance of ProcessedShortcode.');
29 | }
30 |
31 | $this->parent = $parent;
32 | $this->setShortcodes($shortcodes);
33 | }
34 |
35 | /** @return ParsedShortcodeInterface[] */
36 | public function getShortcodes()
37 | {
38 | return $this->shortcodes;
39 | }
40 |
41 | /** @return ProcessedShortcode|null */
42 | public function getParent()
43 | {
44 | return $this->parent;
45 | }
46 |
47 | /**
48 | * @param ParsedShortcodeInterface[] $shortcodes
49 | *
50 | * @return void
51 | */
52 | public function setShortcodes(array $shortcodes)
53 | {
54 | $this->shortcodes = array();
55 | foreach($shortcodes as $shortcode) {
56 | $this->addShortcode($shortcode);
57 | }
58 | }
59 |
60 | /**
61 | * @param ParsedShortcodeInterface $shortcode
62 | *
63 | * @return void
64 | */
65 | private function addShortcode(ParsedShortcodeInterface $shortcode)
66 | {
67 | $this->shortcodes[] = $shortcode;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Event/ReplaceShortcodesEvent.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | class ReplaceShortcodesEvent
15 | {
16 | /** @var ShortcodeInterface|null */
17 | private $shortcode;
18 | /** @var string */
19 | private $text;
20 | /** @var ReplacedShortcode[] */
21 | private $replacements = array();
22 | /** @var string|null */
23 | private $result;
24 |
25 | /**
26 | * @param string $text
27 | * @param ReplacedShortcode[] $replacements
28 | * @param ShortcodeInterface|null $shortcode
29 | */
30 | public function __construct($text, array $replacements, $shortcode = null)
31 | {
32 | if(null !== $shortcode && false === $shortcode instanceof ShortcodeInterface) {
33 | throw new \LogicException('Parameter $shortcode must be an instance of ShortcodeInterface.');
34 | }
35 |
36 | $this->shortcode = $shortcode;
37 | $this->text = $text;
38 |
39 | $this->setReplacements($replacements);
40 | }
41 |
42 | /**
43 | * @param ReplacedShortcode[] $replacements
44 | *
45 | * @return void
46 | */
47 | private function setReplacements(array $replacements)
48 | {
49 | foreach($replacements as $replacement) {
50 | $this->addReplacement($replacement);
51 | }
52 | }
53 |
54 | /** @return void */
55 | private function addReplacement(ReplacedShortcode $replacement)
56 | {
57 | $this->replacements[] = $replacement;
58 | }
59 |
60 | /** @return string */
61 | public function getText()
62 | {
63 | return $this->text;
64 | }
65 |
66 | /** @return ReplacedShortcode[] */
67 | public function getReplacements()
68 | {
69 | return $this->replacements;
70 | }
71 |
72 | /** @return ShortcodeInterface|null */
73 | public function getShortcode()
74 | {
75 | return $this->shortcode;
76 | }
77 |
78 | /**
79 | * @param string $result
80 | *
81 | * @return void
82 | */
83 | public function setResult($result)
84 | {
85 | $this->result = $result;
86 | }
87 |
88 | /** @return string|null */
89 | public function getResult()
90 | {
91 | return $this->result;
92 | }
93 |
94 | /** @return bool */
95 | public function hasResult()
96 | {
97 | return null !== $this->result;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/EventContainer/EventContainer.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | final class EventContainer implements EventContainerInterface
10 | {
11 | /** @psalm-var array> */
12 | private $listeners = array();
13 |
14 | public function __construct()
15 | {
16 | }
17 |
18 | /**
19 | * @param string $event
20 | * @param callable $handler
21 | *
22 | * @return void
23 | */
24 | public function addListener($event, $handler)
25 | {
26 | if(!\in_array($event, Events::getEvents(), true)) {
27 | throw new \InvalidArgumentException(sprintf('Unsupported event %s!', $event));
28 | }
29 |
30 | if(!array_key_exists($event, $this->listeners)) {
31 | $this->listeners[$event] = array();
32 | }
33 |
34 | $this->listeners[$event][] = $handler;
35 | }
36 |
37 | /**
38 | * @param string $event
39 | *
40 | * @psalm-return list
41 | */
42 | public function getListeners($event)
43 | {
44 | return $this->hasEvent($event) ? $this->listeners[$event] : array();
45 | }
46 |
47 | /**
48 | * @param string $name
49 | *
50 | * @return bool
51 | */
52 | private function hasEvent($name)
53 | {
54 | return array_key_exists($name, $this->listeners);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/EventContainer/EventContainerInterface.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 | interface EventContainerInterface
8 | {
9 | /**
10 | * @param string $event
11 | *
12 | * @return callable[]
13 | */
14 | public function getListeners($event);
15 | }
16 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/EventHandler/FilterRawEventHandler.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | final class FilterRawEventHandler
10 | {
11 | /** @var string[] */
12 | private $names = array();
13 |
14 | public function __construct(array $names)
15 | {
16 | foreach($names as $name) {
17 | if(false === is_string($name)) {
18 | throw new \InvalidArgumentException('Expected array of strings!');
19 | }
20 |
21 | $this->names[] = $name;
22 | }
23 | }
24 |
25 | public function __invoke(FilterShortcodesEvent $event)
26 | {
27 | $parent = $event->getParent();
28 | if($parent && \in_array($parent->getName(), $this->names, true)) {
29 | $event->setShortcodes(array());
30 |
31 | return;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/EventHandler/ReplaceJoinEventHandler.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | final class ReplaceJoinEventHandler
10 | {
11 | /** @var string[] */
12 | private $names = array();
13 |
14 | public function __construct(array $names)
15 | {
16 | foreach($names as $name) {
17 | if(false === is_string($name)) {
18 | throw new \InvalidArgumentException('Expected array of strings!');
19 | }
20 |
21 | $this->names[] = $name;
22 | }
23 | }
24 |
25 | public function __invoke(ReplaceShortcodesEvent $event)
26 | {
27 | $shortcode = $event->getShortcode();
28 | if($shortcode && in_array($shortcode->getName(), $this->names)) {
29 | $replaces = array();
30 | foreach($event->getReplacements() as $r) {
31 | $replaces[] = $r->getReplacement();
32 | }
33 |
34 | $event->setResult(implode('', $replaces));
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Events.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 | final class Events
8 | {
9 | const FILTER_SHORTCODES = 'event.filter-shortcodes';
10 | const REPLACE_SHORTCODES = 'event.replace-shortcodes';
11 |
12 | /** @return string[] */
13 | public static function getEvents()
14 | {
15 | return array(static::FILTER_SHORTCODES, static::REPLACE_SHORTCODES);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Handler/ContentHandler.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | final class ContentHandler
10 | {
11 | /**
12 | * [content]text to display[/content]
13 | *
14 | * @param ShortcodeInterface $shortcode
15 | *
16 | * @return null|string
17 | */
18 | public function __invoke(ShortcodeInterface $shortcode)
19 | {
20 | return $shortcode->getContent();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Handler/DeclareHandler.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | final class DeclareHandler
11 | {
12 | /** @var HandlerContainer */
13 | private $handlers;
14 | /** @var string */
15 | private $delimiter;
16 |
17 | /** @param string $delimiter */
18 | public function __construct(HandlerContainer $container, $delimiter = '%')
19 | {
20 | $this->handlers = $container;
21 | $this->delimiter = $delimiter;
22 | }
23 |
24 | /**
25 | * [declare name]Your name is %value%[/declare]
26 | * [name value="Thomas" /]
27 | *
28 | * @param ShortcodeInterface $shortcode
29 | */
30 | public function __invoke(ShortcodeInterface $shortcode)
31 | {
32 | $args = $shortcode->getParameters();
33 | if(empty($args)) {
34 | return;
35 | }
36 | $keys = array_keys($args);
37 | $name = array_shift($keys);
38 | $content = (string)$shortcode->getContent();
39 | $delimiter = $this->delimiter;
40 |
41 | $this->handlers->add($name, function(ShortcodeInterface $shortcode) use($content, $delimiter) {
42 | $args = $shortcode->getParameters();
43 | $keys = array_map(function($key) use($delimiter) { return $delimiter.$key.$delimiter; }, array_keys($args));
44 | /** @var string[] $values */
45 | $values = array_values($args);
46 |
47 | return str_replace($keys, $values, $content);
48 | });
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Handler/EmailHandler.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | final class EmailHandler
10 | {
11 | /**
12 | * [email="example@example.org"]Contact me![/email]
13 | * [email="example@example.org" /]
14 | * [email]example@example.org[/email]
15 | *
16 | * @param ShortcodeInterface $shortcode
17 | *
18 | * @return string
19 | */
20 | public function __invoke(ShortcodeInterface $shortcode)
21 | {
22 | $email = null !== $shortcode->getBbCode() ? $shortcode->getBbCode() : $shortcode->getContent();
23 | $content = $shortcode->getContent() === null ? $email : $shortcode->getContent();
24 |
25 | return ''.(string)$content.'';
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Handler/NameHandler.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | final class NameHandler
10 | {
11 | /**
12 | * [name /]
13 | * [name]content is ignored[/name]
14 | *
15 | * @param ShortcodeInterface $shortcode
16 | *
17 | * @return string
18 | */
19 | public function __invoke(ShortcodeInterface $shortcode)
20 | {
21 | return $shortcode->getName();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Handler/NullHandler.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | final class NullHandler
10 | {
11 | /**
12 | * Special shortcode to discard any input and return empty text
13 | *
14 | * @param ShortcodeInterface $shortcode
15 | *
16 | * @return null
17 | */
18 | public function __invoke(ShortcodeInterface $shortcode)
19 | {
20 | return null;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Handler/PlaceholderHandler.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | final class PlaceholderHandler
10 | {
11 | /** @var string */
12 | private $delimiter;
13 |
14 | /** @param string $delimiter */
15 | public function __construct($delimiter = '%')
16 | {
17 | $this->delimiter = $delimiter;
18 | }
19 |
20 | /**
21 | * [placeholder value=18]You age is %value%[/placeholder]
22 | *
23 | * @param ShortcodeInterface $shortcode
24 | *
25 | * @return mixed
26 | */
27 | public function __invoke(ShortcodeInterface $shortcode)
28 | {
29 | $args = $shortcode->getParameters();
30 | $delimiter = $this->delimiter;
31 | $keys = array_map(function($key) use($delimiter) { return $delimiter.$key.$delimiter; }, array_keys($args));
32 | /** @var string[] $values */
33 | $values = array_values($args);
34 |
35 | return str_replace($keys, $values, (string)$shortcode->getContent());
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Handler/RawHandler.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | final class RawHandler
10 | {
11 | public function __construct()
12 | {
13 | }
14 |
15 | /**
16 | * [raw]any content [with] or [without /] shortcodes[/raw]
17 | *
18 | * @param ProcessedShortcode $shortcode
19 | *
20 | * @return string
21 | */
22 | public function __invoke(ProcessedShortcode $shortcode)
23 | {
24 | return $shortcode->getTextContent();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Handler/SerializerHandler.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | final class SerializerHandler
11 | {
12 | /** @var SerializerInterface */
13 | private $serializer;
14 |
15 | public function __construct(SerializerInterface $serializer)
16 | {
17 | $this->serializer = $serializer;
18 | }
19 |
20 | /**
21 | * [text arg=val /]
22 | * [text arg=val]content[/text]
23 | * [json arg=val /]
24 | * [json arg=val]content[/json]
25 | * [xml arg=val /]
26 | * [xml arg=val]content[/xml]
27 | * [yaml arg=val /]
28 | * [yaml arg=val]content[/yaml]
29 | *
30 | * @param ShortcodeInterface $shortcode
31 | *
32 | * @return string
33 | */
34 | public function __invoke(ShortcodeInterface $shortcode)
35 | {
36 | return $this->serializer->serialize($shortcode);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Handler/UrlHandler.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | final class UrlHandler
10 | {
11 | /**
12 | * [url="http://example.org"]Click![/url]
13 | * [url="http://example.org" /]
14 | * [url]http://example.org[/url]
15 | *
16 | * @param ShortcodeInterface $shortcode
17 | *
18 | * @return string
19 | */
20 | public function __invoke(ShortcodeInterface $shortcode)
21 | {
22 | $url = null !== $shortcode->getBbCode() ? $shortcode->getBbCode() : $shortcode->getContent();
23 |
24 | return ''.(string)$shortcode->getContent().'';
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Handler/WrapHandler.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | final class WrapHandler
10 | {
11 | /** @var string */
12 | private $before;
13 | /** @var string */
14 | private $after;
15 |
16 | /**
17 | * @param string $before
18 | * @param string $after
19 | */
20 | public function __construct($before, $after)
21 | {
22 | $this->before = $before;
23 | $this->after = $after;
24 | }
25 |
26 | /** @return self */
27 | public static function createBold()
28 | {
29 | return new self('', '');
30 | }
31 |
32 | /**
33 | * [b]content[b]
34 | * [strong]content[/strong]
35 | *
36 | * @param ShortcodeInterface $shortcode
37 | *
38 | * @return string
39 | */
40 | public function __invoke(ShortcodeInterface $shortcode)
41 | {
42 | return $this->before.(string)$shortcode->getContent().$this->after;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/HandlerContainer/HandlerContainer.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | final class HandlerContainer implements HandlerContainerInterface
10 | {
11 | /** @psalm-var array */
12 | private $handlers = array();
13 | /** @psalm-var (callable(ShortcodeInterface):string)|null */
14 | private $default = null;
15 |
16 | /**
17 | * @param string $name
18 | * @param callable $handler
19 | * @psalm-param callable(ShortcodeInterface):string $handler
20 | *
21 | * @return $this
22 | */
23 | public function add($name, $handler)
24 | {
25 | $this->guardHandler($handler);
26 |
27 | if (empty($name) || $this->has($name)) {
28 | $msg = 'Invalid name or duplicate shortcode handler for %s!';
29 | throw new \RuntimeException(sprintf($msg, $name));
30 | }
31 |
32 | $this->handlers[$name] = $handler;
33 |
34 | return $this;
35 | }
36 |
37 | /**
38 | * @param string $alias
39 | * @param string $name
40 | *
41 | * @return $this
42 | */
43 | public function addAlias($alias, $name)
44 | {
45 | if (false === $this->has($name)) {
46 | $msg = 'Failed to add an alias %s to non existent handler %s!';
47 | throw new \RuntimeException(sprintf($msg, $alias, $name));
48 | }
49 |
50 | /** @psalm-suppress PossiblyNullArgument */
51 | return $this->add($alias, $this->get($name));
52 | }
53 |
54 | /**
55 | * @param string $name
56 | *
57 | * @return void
58 | */
59 | public function remove($name)
60 | {
61 | if (false === $this->has($name)) {
62 | $msg = 'Failed to remove non existent handler %s!';
63 | throw new \RuntimeException(sprintf($msg, $name));
64 | }
65 |
66 | unset($this->handlers[$name]);
67 | }
68 |
69 | /**
70 | * @param callable $handler
71 | * @psalm-param callable(ShortcodeInterface):string $handler
72 | *
73 | * @return $this
74 | */
75 | public function setDefault($handler)
76 | {
77 | $this->guardHandler($handler);
78 |
79 | $this->default = $handler;
80 |
81 | return $this;
82 | }
83 |
84 | /** @return string[] */
85 | public function getNames()
86 | {
87 | return array_keys($this->handlers);
88 | }
89 |
90 | /**
91 | * @param string $name
92 | *
93 | * @return callable|null
94 | * @psalm-return (callable(ShortcodeInterface):string)|null
95 | */
96 | public function get($name)
97 | {
98 | return $this->has($name) ? $this->handlers[$name] : $this->default;
99 | }
100 |
101 | /**
102 | * @param string $name
103 | *
104 | * @return bool
105 | */
106 | public function has($name)
107 | {
108 | return array_key_exists($name, $this->handlers);
109 | }
110 |
111 | /**
112 | * @param callable $handler
113 | *
114 | * @return void
115 | */
116 | private function guardHandler($handler)
117 | {
118 | if (!is_callable($handler)) {
119 | throw new \RuntimeException('Shortcode handler must be callable!');
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/HandlerContainer/HandlerContainerInterface.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | interface HandlerContainerInterface
10 | {
11 | /**
12 | * Returns handler for given shortcode name or default if it was set before.
13 | * If no handler is found, returns null.
14 | *
15 | * @param string $name Shortcode name
16 | *
17 | * @return callable|null
18 | * @psalm-return (callable(ShortcodeInterface):string)|null
19 | */
20 | public function get($name);
21 | }
22 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/HandlerContainer/ImmutableHandlerContainer.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | final class ImmutableHandlerContainer implements HandlerContainerInterface
10 | {
11 | /** @var HandlerContainer */
12 | private $handlers;
13 |
14 | public function __construct(HandlerContainer $handlers)
15 | {
16 | $this->handlers = clone $handlers;
17 | }
18 |
19 | /**
20 | * @param string $name
21 | *
22 | * @return callable|null
23 | * @psalm-return (callable(ShortcodeInterface):string)|null
24 | */
25 | public function get($name)
26 | {
27 | return $this->handlers->get($name);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Parser/ParserInterface.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | interface ParserInterface
10 | {
11 | /**
12 | * Parse single shortcode match into object
13 | *
14 | * @param string $text
15 | *
16 | * @return ParsedShortcodeInterface[]
17 | */
18 | public function parse($text);
19 | }
20 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Parser/RegexParser.php:
--------------------------------------------------------------------------------
1 |
12 | */
13 | final class RegexParser implements ParserInterface
14 | {
15 | /** @var SyntaxInterface */
16 | private $syntax;
17 | /** @var non-empty-string */
18 | private $shortcodeRegex;
19 | /** @var non-empty-string */
20 | private $singleShortcodeRegex;
21 | /** @var non-empty-string */
22 | private $parametersRegex;
23 |
24 | /** @param SyntaxInterface|null $syntax */
25 | public function __construct($syntax = null)
26 | {
27 | if(null !== $syntax && false === $syntax instanceof SyntaxInterface) {
28 | throw new \LogicException('Parameter $syntax must be an instance of SyntaxInterface.');
29 | }
30 |
31 | $this->syntax = $syntax ?: new Syntax();
32 | $this->shortcodeRegex = RegexBuilderUtility::buildShortcodeRegex($this->syntax);
33 | $this->singleShortcodeRegex = RegexBuilderUtility::buildSingleShortcodeRegex($this->syntax);
34 | $this->parametersRegex = RegexBuilderUtility::buildParametersRegex($this->syntax);
35 | }
36 |
37 | /**
38 | * @param string $text
39 | *
40 | * @return ParsedShortcode[]
41 | */
42 | public function parse($text)
43 | {
44 | preg_match_all($this->shortcodeRegex, $text, $matches, PREG_OFFSET_CAPTURE);
45 |
46 | // loop instead of array_map to pass the arguments explicitly
47 | $shortcodes = array();
48 | foreach($matches[0] as $match) {
49 | $offset = mb_strlen(substr($text, 0, $match[1]), 'utf-8');
50 | $shortcodes[] = $this->parseSingle($match[0], $offset);
51 | }
52 |
53 | return array_filter($shortcodes);
54 | }
55 |
56 | /**
57 | * @param string $text
58 | * @param int $offset
59 | *
60 | * @return ParsedShortcode
61 | */
62 | private function parseSingle($text, $offset)
63 | {
64 | preg_match($this->singleShortcodeRegex, $text, $matches, PREG_OFFSET_CAPTURE);
65 |
66 | /** @psalm-var array $matches */
67 | $name = $matches['name'][0];
68 | $parameters = isset($matches['parameters'][0]) ? $this->parseParameters($matches['parameters'][0]) : array();
69 | $bbCode = isset($matches['bbCode'][0]) && $matches['bbCode'][1] !== -1
70 | ? $this->extractValue($matches['bbCode'][0])
71 | : null;
72 | $content = isset($matches['content'][0]) && $matches['content'][1] !== -1 ? $matches['content'][0] : null;
73 |
74 | return new ParsedShortcode(new Shortcode($name, $parameters, $content, $bbCode), $text, $offset);
75 | }
76 |
77 | /**
78 | * @param string $text
79 | *
80 | * @psalm-return array
81 | */
82 | private function parseParameters($text)
83 | {
84 | preg_match_all($this->parametersRegex, $text, $argsMatches);
85 |
86 | // loop because PHP 5.3 can't handle $this properly and I want separate methods
87 | $return = array();
88 | foreach ($argsMatches[1] as $item) {
89 | /** @psalm-var array{0:string,1:string} $parts */
90 | $parts = explode($this->syntax->getParameterValueSeparator(), $item, 2);
91 | $return[trim($parts[0])] = $this->parseValue(isset($parts[1]) ? $parts[1] : null);
92 | }
93 |
94 | return $return;
95 | }
96 |
97 | /**
98 | * @param string|null $value
99 | *
100 | * @return string|null
101 | */
102 | private function parseValue($value)
103 | {
104 | return null === $value ? null : $this->extractValue(trim($value));
105 | }
106 |
107 | /**
108 | * @param string $value
109 | *
110 | * @return string
111 | */
112 | private function extractValue($value)
113 | {
114 | $length = strlen($this->syntax->getParameterValueDelimiter());
115 |
116 | return $this->isDelimitedValue($value) ? substr($value, $length, -1 * $length) : $value;
117 | }
118 |
119 | /**
120 | * @param string $value
121 | *
122 | * @return bool
123 | */
124 | private function isDelimitedValue($value)
125 | {
126 | return preg_match('/^'.$this->syntax->getParameterValueDelimiter().'/us', $value)
127 | && preg_match('/'.$this->syntax->getParameterValueDelimiter().'$/us', $value);
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Processor/ProcessorContext.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | final class ProcessorContext
11 | {
12 | /**
13 | * @var ShortcodeInterface
14 | * @psalm-suppress PropertyNotSetInConstructor
15 | */
16 | public $shortcode;
17 |
18 | /** @var ProcessedShortcode|null */
19 | public $parent = null;
20 |
21 | /**
22 | * @var ProcessorInterface
23 | * @psalm-suppress PropertyNotSetInConstructor
24 | */
25 | public $processor;
26 |
27 | /**
28 | * @var string
29 | * @psalm-suppress PropertyNotSetInConstructor
30 | */
31 | public $textContent;
32 | /** @var int */
33 | public $position = 0;
34 | /** @psalm-var array */
35 | public $namePosition = array();
36 | /** @var string */
37 | public $text = '';
38 | /** @var string */
39 | public $shortcodeText = '';
40 | /** @var int */
41 | public $iterationNumber = 0;
42 | /** @var int */
43 | public $recursionLevel = 0;
44 | /**
45 | * @var int
46 | * @psalm-suppress PropertyNotSetInConstructor
47 | */
48 | public $offset;
49 | /**
50 | * @var int
51 | * @psalm-suppress PropertyNotSetInConstructor
52 | */
53 | public $baseOffset;
54 |
55 | public function __construct()
56 | {
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Processor/ProcessorInterface.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 | interface ProcessorInterface
8 | {
9 | /**
10 | * Process text using registered shortcode handlers
11 | *
12 | * @param string $text Text containing shortcodes
13 | *
14 | * @return string Text with replaced shortcodes
15 | */
16 | public function process($text);
17 | }
18 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Serializer/JsonSerializer.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | final class JsonSerializer implements SerializerInterface
11 | {
12 | public function serialize(ShortcodeInterface $shortcode)
13 | {
14 | return json_encode(array(
15 | 'name' => $shortcode->getName(),
16 | 'parameters' => $shortcode->getParameters(),
17 | 'content' => $shortcode->getContent(),
18 | 'bbCode' => $shortcode->getBbCode(),
19 | ));
20 | }
21 |
22 | /**
23 | * @param string $text
24 | *
25 | * @return Shortcode
26 | */
27 | public function unserialize($text)
28 | {
29 | /** @psalm-var array{name:string,parameters:array,bbCode:string|null,content:string|null}|null $data */
30 | $data = json_decode($text, true);
31 |
32 | if (!is_array($data)) {
33 | throw new \InvalidArgumentException('Invalid JSON, cannot unserialize Shortcode!');
34 | }
35 | if (!array_diff_key($data, array('name', 'parameters', 'content'))) {
36 | throw new \InvalidArgumentException('Malformed Shortcode JSON, expected name, parameters, and content!');
37 | }
38 |
39 | /** @var string $name */
40 | $name = array_key_exists('name', $data) ? $data['name'] : null;
41 | $parameters = array_key_exists('parameters', $data) ? $data['parameters'] : array();
42 | $content = array_key_exists('content', $data) ? $data['content'] : null;
43 | $bbCode = array_key_exists('bbCode', $data) ? $data['bbCode'] : null;
44 |
45 | /** @psalm-suppress DocblockTypeContradiction */
46 | if(!is_array($parameters)) {
47 | throw new \InvalidArgumentException('Parameters must be an array!');
48 | }
49 |
50 | return new Shortcode($name, $parameters, $content, $bbCode);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Serializer/SerializerInterface.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | interface SerializerInterface
10 | {
11 | /**
12 | * Serializes Shortcode class instance into given format
13 | *
14 | * @param ShortcodeInterface $shortcode Instance to serialize
15 | *
16 | * @return string
17 | */
18 | public function serialize(ShortcodeInterface $shortcode);
19 |
20 | /**
21 | * Loads back Shortcode instance from serialized format
22 | *
23 | * @param string $text
24 | *
25 | * @return ShortcodeInterface
26 | */
27 | public function unserialize($text);
28 | }
29 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Serializer/TextSerializer.php:
--------------------------------------------------------------------------------
1 |
12 | */
13 | final class TextSerializer implements SerializerInterface
14 | {
15 | /** @var SyntaxInterface */
16 | private $syntax;
17 |
18 | /** @param SyntaxInterface|null $syntax */
19 | public function __construct($syntax = null)
20 | {
21 | if(null !== $syntax && false === $syntax instanceof SyntaxInterface) {
22 | throw new \LogicException('Parameter $syntax must be an instance of SyntaxInterface.');
23 | }
24 |
25 | $this->syntax = $syntax ?: new Syntax();
26 | }
27 |
28 | /** @inheritDoc */
29 | public function serialize(ShortcodeInterface $shortcode)
30 | {
31 | $open = $this->syntax->getOpeningTag();
32 | $close = $this->syntax->getClosingTag();
33 | $marker = $this->syntax->getClosingTagMarker();
34 |
35 | $parameters = $this->serializeParameters($shortcode->getParameters());
36 | $bbCode = null !== $shortcode->getBbCode()
37 | ? $this->serializeValue($shortcode->getBbCode())
38 | : '';
39 | $return = $open.$shortcode->getName().$bbCode.$parameters;
40 |
41 | return null === $shortcode->getContent()
42 | ? $return.' '.$marker.$close
43 | : $return.$close.(string)$shortcode->getContent().$open.$marker.$shortcode->getName().$close;
44 | }
45 |
46 | /**
47 | * @psalm-param array $parameters
48 | *
49 | * @return string
50 | */
51 | private function serializeParameters(array $parameters)
52 | {
53 | // unfortunately array_reduce() does not support keys
54 | $return = '';
55 | foreach ($parameters as $key => $value) {
56 | $return .= ' '.$key.$this->serializeValue($value);
57 | }
58 |
59 | return $return;
60 | }
61 |
62 | /**
63 | * @param string|null $value
64 | *
65 | * @return string
66 | */
67 | private function serializeValue($value)
68 | {
69 | if (null === $value) {
70 | return '';
71 | }
72 |
73 | $delimiter = $this->syntax->getParameterValueDelimiter();
74 | $separator = $this->syntax->getParameterValueSeparator();
75 |
76 | return $separator.(preg_match('/^\w+$/u', $value)
77 | ? $value
78 | : $delimiter.$value.$delimiter);
79 | }
80 |
81 | public function unserialize($text)
82 | {
83 | $parser = new RegexParser();
84 |
85 | $shortcodes = $parser->parse($text);
86 |
87 | if (empty($shortcodes)) {
88 | $msg = 'Failed to unserialize shortcode from text %s!';
89 | throw new \InvalidArgumentException(sprintf($msg, $text));
90 | }
91 | if (count($shortcodes) > 1) {
92 | $msg = 'Provided text %s contains more than one shortcode!';
93 | throw new \InvalidArgumentException(sprintf($msg, $text));
94 | }
95 |
96 | /** @var ShortcodeInterface $parsed */
97 | $parsed = array_shift($shortcodes);
98 |
99 | $name = $parsed->getName();
100 | $parameters = $parsed->getParameters();
101 | $content = $parsed->getContent();
102 | $bbCode = $parsed->getBbCode();
103 |
104 | return new Shortcode($name, $parameters, $content, $bbCode);
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Serializer/XmlSerializer.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | final class XmlSerializer implements SerializerInterface
11 | {
12 | /**
13 | *
14 | * BBCODE
15 | *
16 | * VALUE
17 | * VALUE
18 | *
19 | * CONTENT>
20 | *
21 | *
22 | * @param ShortcodeInterface $shortcode
23 | *
24 | * @return string
25 | */
26 | public function serialize(ShortcodeInterface $shortcode)
27 | {
28 | $doc = new \DOMDocument('1.0', 'UTF-8');
29 | $doc->preserveWhiteSpace = false;
30 | $doc->formatOutput = true;
31 |
32 | $code = $doc->createElement('shortcode');
33 | $code->setAttribute('name', $shortcode->getName());
34 | $xml = $doc->appendChild($code);
35 | $xml->appendChild($this->createCDataNode($doc, 'bbCode', $shortcode->getBbCode()));
36 |
37 | $parameters = $xml->appendChild($doc->createElement('parameters'));
38 | foreach($shortcode->getParameters() as $key => $value) {
39 | $parameter = $doc->createElement('parameter');
40 | $parameter->setAttribute('name', $key);
41 | if(null !== $value) {
42 | $parameter->appendChild($doc->createCDATASection($value));
43 | }
44 |
45 | $parameters->appendChild($parameter);
46 | }
47 |
48 | $xml->appendChild($this->createCDataNode($doc, 'content', $shortcode->getContent()));
49 |
50 | return $doc->saveXML();
51 | }
52 |
53 | /**
54 | * @param \DOMDocument $doc
55 | * @param string $name
56 | * @param string|null $content
57 | *
58 | * @return \DOMElement
59 | */
60 | private function createCDataNode(\DOMDocument $doc, $name, $content)
61 | {
62 | $node = $doc->createElement($name);
63 |
64 | if(null !== $content) {
65 | $node->appendChild($doc->createCDATASection($content));
66 | }
67 |
68 | return $node;
69 | }
70 |
71 | /**
72 | * @param string $text
73 | *
74 | * @return Shortcode
75 | */
76 | public function unserialize($text)
77 | {
78 | $xml = new \DOMDocument();
79 | $internalErrors = libxml_use_internal_errors(true);
80 | if(!$text || !$xml->loadXML($text)) {
81 | libxml_use_internal_errors($internalErrors);
82 | throw new \InvalidArgumentException('Failed to parse provided XML!');
83 | }
84 | libxml_use_internal_errors($internalErrors);
85 |
86 | $xpath = new \DOMXPath($xml);
87 | $shortcode = $xpath->query('/shortcode');
88 | if($shortcode->length !== 1) {
89 | throw new \InvalidArgumentException('Invalid shortcode XML!');
90 | }
91 | /** @psalm-suppress PossiblyNullArgument */
92 | $name = $this->getAttribute($shortcode->item(0), 'name');
93 |
94 | $bbCode = $this->getValue($xpath->query('/shortcode/bbCode'));
95 | $content = $this->getValue($xpath->query('/shortcode/content'));
96 |
97 | $parameters = array();
98 | $elements = $xpath->query('/shortcode/parameters/parameter');
99 | for($i = 0; $i < $elements->length; $i++) {
100 | $node = $elements->item($i);
101 |
102 | /** @psalm-suppress PossiblyNullReference */
103 | $parameters[$this->getAttribute($node, 'name')] = $node->hasChildNodes() ? $node->nodeValue : null;
104 | }
105 |
106 | return new Shortcode($name, $parameters, $content, $bbCode);
107 | }
108 |
109 | /**
110 | * @param \DOMNodeList $node
111 | *
112 | * @return string|null
113 | */
114 | private function getValue(\DOMNodeList $node)
115 | {
116 | /** @psalm-suppress PossiblyNullReference,PossiblyNullPropertyFetch */
117 | return $node->length === 1 && $node->item(0)->hasChildNodes()
118 | ? $node->item(0)->nodeValue
119 | : null;
120 | }
121 |
122 | /**
123 | * @param \DOMNode $node
124 | * @param string $name
125 | *
126 | * @return string
127 | */
128 | private function getAttribute(\DOMNode $node, $name)
129 | {
130 | /**
131 | * @var \DOMNode $attribute
132 | * @psalm-suppress NullReference
133 | */
134 | $attribute = $node->attributes->getNamedItem($name);
135 |
136 | /** @psalm-suppress DocblockTypeContradiction,RiskyTruthyFalsyComparison */
137 | if(!$attribute || !$attribute->nodeValue) {
138 | throw new \InvalidArgumentException('Invalid shortcode XML!');
139 | }
140 |
141 | return $attribute->nodeValue;
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Serializer/YamlSerializer.php:
--------------------------------------------------------------------------------
1 |
10 | */
11 | final class YamlSerializer implements SerializerInterface
12 | {
13 | public function serialize(ShortcodeInterface $shortcode)
14 | {
15 | return Yaml::dump(array(
16 | 'name' => $shortcode->getName(),
17 | 'parameters' => $shortcode->getParameters(),
18 | 'content' => $shortcode->getContent(),
19 | 'bbCode' => $shortcode->getBbCode(),
20 | ));
21 | }
22 |
23 | /**
24 | * @param string $text
25 | *
26 | * @return Shortcode
27 | */
28 | public function unserialize($text)
29 | {
30 | /** @psalm-var array{name:string,parameters:array,bbCode:string|null,content:string|null}|null $data */
31 | $data = Yaml::parse($text);
32 |
33 | if(!is_array($data)) {
34 | throw new \InvalidArgumentException('Invalid YAML, cannot unserialize Shortcode!');
35 | }
36 | if (!array_intersect(array_keys($data), array('name', 'parameters', 'content'))) {
37 | throw new \InvalidArgumentException('Malformed shortcode YAML, expected name, parameters, and content!');
38 | }
39 |
40 | /** @var string $name */
41 | $name = array_key_exists('name', $data) ? $data['name'] : null;
42 | $parameters = array_key_exists('parameters', $data) ? $data['parameters'] : array();
43 | $content = array_key_exists('content', $data) ? $data['content'] : null;
44 | $bbCode = array_key_exists('bbCode', $data) ? $data['bbCode'] : null;
45 |
46 | /** @psalm-suppress DocblockTypeContradiction */
47 | if(!is_array($parameters)) {
48 | throw new \InvalidArgumentException('Parameters must be an array!');
49 | }
50 |
51 | return new Shortcode($name, $parameters, $content, $bbCode);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Shortcode/AbstractShortcode.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 | abstract class AbstractShortcode
8 | {
9 | /** @var string */
10 | protected $name;
11 | /** @psalm-var array */
12 | protected $parameters = array();
13 | /** @var string|null */
14 | protected $content;
15 | /** @var string|null */
16 | protected $bbCode;
17 |
18 | /** @return bool */
19 | public function hasContent()
20 | {
21 | return $this->content !== null;
22 | }
23 |
24 | /** @return string */
25 | public function getName()
26 | {
27 | return $this->name;
28 | }
29 |
30 | /** @psalm-return array */
31 | public function getParameters()
32 | {
33 | return $this->parameters;
34 | }
35 |
36 | /**
37 | * @param string $name
38 | *
39 | * @return bool
40 | */
41 | public function hasParameter($name)
42 | {
43 | return array_key_exists($name, $this->parameters);
44 | }
45 |
46 | /** @return bool */
47 | public function hasParameters()
48 | {
49 | return (bool)$this->parameters;
50 | }
51 |
52 | /**
53 | * @param string $name
54 | * @param string|null $default
55 | *
56 | * @psalm-return string|null
57 | */
58 | public function getParameter($name, $default = null)
59 | {
60 | return $this->hasParameter($name) ? $this->parameters[$name] : $default;
61 | }
62 |
63 | /**
64 | * @param int $index
65 | *
66 | * @return string|null
67 | */
68 | public function getParameterAt($index)
69 | {
70 | $keys = array_keys($this->parameters);
71 |
72 | return array_key_exists($index, $keys) ? $keys[$index] : null;
73 | }
74 |
75 | /** @return string|null */
76 | public function getContent()
77 | {
78 | return $this->content;
79 | }
80 |
81 | /** @return string|null */
82 | public function getBbCode()
83 | {
84 | return $this->bbCode;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Shortcode/ParsedShortcode.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 | final class ParsedShortcode extends AbstractShortcode implements ParsedShortcodeInterface
8 | {
9 | /** @var string */
10 | private $text;
11 | /** @var int */
12 | private $offset;
13 |
14 | /**
15 | * @param string $text
16 | * @param int $offset
17 | */
18 | public function __construct(ShortcodeInterface $shortcode, $text, $offset)
19 | {
20 | $this->name = $shortcode->getName();
21 | $this->parameters = $shortcode->getParameters();
22 | $this->content = $shortcode->getContent();
23 | $this->bbCode = $shortcode->getBbCode();
24 | $this->text = $text;
25 | $this->offset = $offset;
26 | }
27 |
28 | public function withContent($content)
29 | {
30 | $self = clone $this;
31 | $self->content = $content;
32 |
33 | return $self;
34 | }
35 |
36 | /** @return string */
37 | public function getText()
38 | {
39 | return $this->text;
40 | }
41 |
42 | /** @return int */
43 | public function getOffset()
44 | {
45 | return $this->offset;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Shortcode/ParsedShortcodeInterface.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 | interface ParsedShortcodeInterface extends ShortcodeInterface
8 | {
9 | /**
10 | * Returns exact shortcode text
11 | *
12 | * @return string
13 | */
14 | public function getText();
15 |
16 | /**
17 | * Returns string position in the parent text
18 | *
19 | * @return int
20 | */
21 | public function getOffset();
22 | }
23 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Shortcode/ProcessedShortcode.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | final class ProcessedShortcode extends AbstractShortcode implements ParsedShortcodeInterface
11 | {
12 | /** @var ProcessedShortcode|null */
13 | private $parent;
14 | /** @var int */
15 | private $position;
16 | /** @var int */
17 | private $namePosition;
18 | /** @var string */
19 | private $text;
20 | /** @var string */
21 | private $textContent;
22 | /** @var int */
23 | private $offset;
24 | /** @var int */
25 | private $baseOffset;
26 | /** @var string */
27 | private $shortcodeText;
28 | /** @var int */
29 | private $iterationNumber;
30 | /** @var int */
31 | private $recursionLevel;
32 | /** @var ProcessorInterface */
33 | private $processor;
34 |
35 | private function __construct(ProcessorContext $context)
36 | {
37 | // basic properties
38 | $this->name = $context->shortcode->getName();
39 | $this->parameters = $context->shortcode->getParameters();
40 | $this->content = $context->shortcode->getContent();
41 | $this->bbCode = $context->shortcode->getBbCode();
42 | $this->textContent = $context->textContent;
43 |
44 | // runtime context
45 | $this->parent = $context->parent;
46 | $this->position = $context->position;
47 | $this->namePosition = $context->namePosition[$this->name];
48 | $this->text = $context->text;
49 | $this->shortcodeText = $context->shortcodeText;
50 |
51 | // processor state
52 | $this->iterationNumber = $context->iterationNumber;
53 | $this->recursionLevel = $context->recursionLevel;
54 | $this->processor = $context->processor;
55 |
56 | // text context
57 | $this->offset = $context->offset;
58 | $this->baseOffset = $context->baseOffset;
59 | }
60 |
61 | /** @return self */
62 | public static function createFromContext(ProcessorContext $context)
63 | {
64 | return new self($context);
65 | }
66 |
67 | /**
68 | * @param string|null $content
69 | *
70 | * @return self
71 | */
72 | public function withContent($content)
73 | {
74 | $self = clone $this;
75 | $self->content = $content;
76 |
77 | return $self;
78 | }
79 |
80 | /**
81 | * @param string $name
82 | *
83 | * @return bool
84 | */
85 | public function hasAncestor($name)
86 | {
87 | $self = $this;
88 |
89 | while($self = $self->getParent()) {
90 | if($self->getName() === $name) {
91 | return true;
92 | }
93 | }
94 |
95 | return false;
96 | }
97 |
98 | /** @return ProcessedShortcode|null */
99 | public function getParent()
100 | {
101 | return $this->parent;
102 | }
103 |
104 | /** @return string */
105 | public function getTextContent()
106 | {
107 | return $this->textContent;
108 | }
109 |
110 | /** @return int */
111 | public function getPosition()
112 | {
113 | return $this->position;
114 | }
115 |
116 | /** @return int */
117 | public function getNamePosition()
118 | {
119 | return $this->namePosition;
120 | }
121 |
122 | /** @return string */
123 | public function getText()
124 | {
125 | return $this->text;
126 | }
127 |
128 | /** @return string */
129 | public function getShortcodeText()
130 | {
131 | return $this->shortcodeText;
132 | }
133 |
134 | /** @return int */
135 | public function getOffset()
136 | {
137 | return $this->offset;
138 | }
139 |
140 | /** @return int */
141 | public function getBaseOffset()
142 | {
143 | return $this->baseOffset;
144 | }
145 |
146 | /** @return int */
147 | public function getIterationNumber()
148 | {
149 | return $this->iterationNumber;
150 | }
151 |
152 | /** @return int */
153 | public function getRecursionLevel()
154 | {
155 | return $this->recursionLevel;
156 | }
157 |
158 | /** @return ProcessorInterface */
159 | public function getProcessor()
160 | {
161 | return $this->processor;
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Shortcode/ReplacedShortcode.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 | final class ReplacedShortcode extends AbstractShortcode
8 | {
9 | /** @var string */
10 | private $replacement;
11 | /** @var string */
12 | private $text;
13 | /** @var int */
14 | private $offset;
15 |
16 | /** @param string $replacement */
17 | public function __construct(ParsedShortcodeInterface $shortcode, $replacement)
18 | {
19 | $this->name = $shortcode->getName();
20 | $this->parameters = $shortcode->getParameters();
21 | $this->content = $shortcode->getContent();
22 | $this->bbCode = $shortcode->getBbCode();
23 | $this->text = $shortcode->getText();
24 | $this->offset = $shortcode->getOffset();
25 |
26 | $this->replacement = $replacement;
27 | }
28 |
29 | /** @return string */
30 | public function getReplacement()
31 | {
32 | return $this->replacement;
33 | }
34 |
35 | /** @return string */
36 | public function getText()
37 | {
38 | return $this->text;
39 | }
40 |
41 | /** @return int */
42 | public function getOffset()
43 | {
44 | return $this->offset;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Shortcode/Shortcode.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 | final class Shortcode extends AbstractShortcode implements ShortcodeInterface
8 | {
9 | /**
10 | * @param string $name
11 | * @param array $parameters
12 | * @psalm-param array $parameters
13 | * @param string|null $content
14 | * @param string|null $bbCode
15 | */
16 | public function __construct($name, array $parameters, $content, $bbCode = null)
17 | {
18 | /** @psalm-suppress RedundantConditionGivenDocblockType, DocblockTypeContradiction */
19 | if(false === is_string($name) || '' === $name) {
20 | throw new \InvalidArgumentException('Shortcode name must be a non-empty string!');
21 | }
22 |
23 | /** @psalm-suppress MissingClosureParamType, MissingClosureReturnType */
24 | $isStringOrNull = function($value) { return is_string($value) || null === $value; };
25 | if(count(array_filter($parameters, $isStringOrNull)) !== count($parameters)) {
26 | throw new \InvalidArgumentException('Parameter values must be either string or empty (null)!');
27 | }
28 |
29 | $this->name = $name;
30 | $this->parameters = $parameters;
31 | $this->content = $content;
32 | $this->bbCode = $bbCode;
33 | }
34 |
35 | public function withContent($content)
36 | {
37 | return new self($this->name, $this->parameters, $content, $this->bbCode);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Shortcode/ShortcodeInterface.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 | interface ShortcodeInterface
8 | {
9 | /**
10 | * Returns new instance of given shortcode with changed content
11 | *
12 | * @param string $content
13 | *
14 | * @return self
15 | */
16 | public function withContent($content);
17 |
18 | /**
19 | * Returns shortcode name
20 | *
21 | * @return string
22 | */
23 | public function getName();
24 |
25 | /**
26 | * Returns associative array(name => value) of shortcode parameters
27 | *
28 | * @return array
29 | * @psalm-return array
30 | */
31 | public function getParameters();
32 |
33 | /**
34 | * Returns parameter value using its name, will return null for parameter
35 | * without value
36 | *
37 | * @param string $name Parameter name
38 | * @param string|null $default Value returned if there is no parameter with given name
39 | *
40 | * @return string|null
41 | */
42 | public function getParameter($name, $default = null);
43 |
44 | /**
45 | * Returns shortcode content (data between opening and closing tag). Null
46 | * means that shortcode had no content (was self closing), do not confuse
47 | * that with empty string (hint: use strict comparison operator ===).
48 | *
49 | * @return string|null
50 | */
51 | public function getContent();
52 |
53 | /**
54 | * Returns the so-called "BBCode" fragment when shortcode name is treated
55 | * like a parameter, eg.: [name="value" /]
56 | *
57 | * @return string|null
58 | */
59 | public function getBbCode();
60 | }
61 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Syntax/CommonSyntax.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 | final class CommonSyntax implements SyntaxInterface
8 | {
9 | /** @return non-empty-string */
10 | public function getOpeningTag()
11 | {
12 | return '[';
13 | }
14 |
15 | /** @return non-empty-string */
16 | public function getClosingTag()
17 | {
18 | return ']';
19 | }
20 |
21 | /** @return non-empty-string */
22 | public function getClosingTagMarker()
23 | {
24 | return '/';
25 | }
26 |
27 | /** @return non-empty-string */
28 | public function getParameterValueSeparator()
29 | {
30 | return '=';
31 | }
32 |
33 | /** @return non-empty-string */
34 | public function getParameterValueDelimiter()
35 | {
36 | return '"';
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Syntax/Syntax.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 | final class Syntax implements SyntaxInterface
8 | {
9 | /** @var non-empty-string|null */
10 | private $openingTag;
11 | /** @var non-empty-string|null */
12 | private $closingTag;
13 | /** @var non-empty-string|null */
14 | private $closingTagMarker;
15 | /** @var non-empty-string|null */
16 | private $parameterValueSeparator;
17 | /** @var non-empty-string|null */
18 | private $parameterValueDelimiter;
19 |
20 | /**
21 | * @param non-empty-string|null $openingTag
22 | * @param non-empty-string|null $closingTag
23 | * @param non-empty-string|null $closingTagMarker
24 | * @param non-empty-string|null $parameterValueSeparator
25 | * @param non-empty-string|null $parameterValueDelimiter
26 | */
27 | public function __construct(
28 | $openingTag = null,
29 | $closingTag = null,
30 | $closingTagMarker = null,
31 | $parameterValueSeparator = null,
32 | $parameterValueDelimiter = null
33 | ) {
34 | $this->openingTag = $openingTag;
35 | $this->closingTag = $closingTag;
36 | $this->closingTagMarker = $closingTagMarker;
37 | $this->parameterValueSeparator = $parameterValueSeparator;
38 | $this->parameterValueDelimiter = $parameterValueDelimiter;
39 | }
40 |
41 | /** @return non-empty-string */
42 | public function getOpeningTag()
43 | {
44 | return null !== $this->openingTag ? $this->openingTag : '[';
45 | }
46 |
47 | /** @return non-empty-string */
48 | public function getClosingTag()
49 | {
50 | return null !== $this->closingTag ? $this->closingTag : ']';
51 | }
52 |
53 | /** @return non-empty-string */
54 | public function getClosingTagMarker()
55 | {
56 | return null !== $this->closingTagMarker ? $this->closingTagMarker : '/';
57 | }
58 |
59 | /** @return non-empty-string */
60 | public function getParameterValueSeparator()
61 | {
62 | return null !== $this->parameterValueSeparator ? $this->parameterValueSeparator : '=';
63 | }
64 |
65 | /** @return non-empty-string */
66 | public function getParameterValueDelimiter()
67 | {
68 | return null !== $this->parameterValueDelimiter ? $this->parameterValueDelimiter : '"';
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Syntax/SyntaxBuilder.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 | final class SyntaxBuilder
8 | {
9 | /** @var non-empty-string|null */
10 | private $openingTag;
11 | /** @var non-empty-string|null */
12 | private $closingTag;
13 | /** @var non-empty-string|null */
14 | private $closingTagMarker;
15 | /** @var non-empty-string|null */
16 | private $parameterValueSeparator;
17 | /** @var non-empty-string|null */
18 | private $parameterValueDelimiter;
19 |
20 | public function __construct()
21 | {
22 | }
23 |
24 | /** @return Syntax */
25 | public function getSyntax()
26 | {
27 | return new Syntax(
28 | $this->openingTag,
29 | $this->closingTag,
30 | $this->closingTagMarker,
31 | $this->parameterValueSeparator,
32 | $this->parameterValueDelimiter
33 | );
34 | }
35 |
36 | /**
37 | * @param non-empty-string $tag
38 | *
39 | * @return $this
40 | */
41 | public function setOpeningTag($tag)
42 | {
43 | $this->openingTag = $tag;
44 |
45 | return $this;
46 | }
47 |
48 | /**
49 | * @param non-empty-string $tag
50 | *
51 | * @return $this
52 | */
53 | public function setClosingTag($tag)
54 | {
55 | $this->closingTag = $tag;
56 |
57 | return $this;
58 | }
59 |
60 | /**
61 | * @param non-empty-string $marker
62 | *
63 | * @return $this
64 | */
65 | public function setClosingTagMarker($marker)
66 | {
67 | $this->closingTagMarker = $marker;
68 |
69 | return $this;
70 | }
71 |
72 | /**
73 | * @param non-empty-string $separator
74 | *
75 | * @return $this
76 | */
77 | public function setParameterValueSeparator($separator)
78 | {
79 | $this->parameterValueSeparator = $separator;
80 |
81 | return $this;
82 | }
83 |
84 | /**
85 | * @param non-empty-string $delimiter
86 | *
87 | * @return $this
88 | */
89 | public function setParameterValueDelimiter($delimiter)
90 | {
91 | $this->parameterValueDelimiter = $delimiter;
92 |
93 | return $this;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Syntax/SyntaxInterface.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 | interface SyntaxInterface
8 | {
9 | /** @return non-empty-string */
10 | public function getOpeningTag();
11 |
12 | /** @return non-empty-string */
13 | public function getClosingTag();
14 |
15 | /** @return non-empty-string */
16 | public function getClosingTagMarker();
17 |
18 | /** @return non-empty-string */
19 | public function getParameterValueSeparator();
20 |
21 | /** @return non-empty-string */
22 | public function getParameterValueDelimiter();
23 | }
24 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/src/Utility/RegexBuilderUtility.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | final class RegexBuilderUtility
10 | {
11 | /** @return non-empty-string */
12 | public static function buildNameRegex()
13 | {
14 | return '[a-zA-Z0-9-_\\*]+';
15 | }
16 |
17 | /** @return non-empty-string */
18 | public static function buildShortcodeRegex(SyntaxInterface $syntax)
19 | {
20 | return '~('.self::createShortcodeRegexContent($syntax).')~us';
21 | }
22 |
23 | /** @return non-empty-string */
24 | public static function buildSingleShortcodeRegex(SyntaxInterface $syntax)
25 | {
26 | return '~(\A'.self::createShortcodeRegexContent($syntax).'\Z)~us';
27 | }
28 |
29 | /** @return non-empty-string */
30 | public static function buildParametersRegex(SyntaxInterface $syntax)
31 | {
32 | $equals = self::quote($syntax->getParameterValueSeparator());
33 | $string = self::quote($syntax->getParameterValueDelimiter());
34 |
35 | $space = '\s*';
36 | // lookahead test for either space or end of string
37 | $empty = '(?=\s|$)';
38 | // equals sign and alphanumeric value
39 | $simple = $space.$equals.$space.'[^\s]+';
40 | // equals sign and value without unescaped string delimiters enclosed in them
41 | $complex = $space.$equals.$space.$string.'([^'.$string.'\\\\]*(?:\\\\.[^'.$string.'\\\\]*)*?)'.$string;
42 |
43 | return '~(?:\s*(\w+(?:'.$complex.'|'.$simple.'|'.$empty.')))~us';
44 | }
45 |
46 | /** @return non-empty-string */
47 | private static function createShortcodeRegexContent(SyntaxInterface $syntax)
48 | {
49 | $open = self::quote($syntax->getOpeningTag());
50 | $slash = self::quote($syntax->getClosingTagMarker());
51 | $close = self::quote($syntax->getClosingTag());
52 | $equals = self::quote($syntax->getParameterValueSeparator());
53 | $string = self::quote($syntax->getParameterValueDelimiter());
54 |
55 | $space = '\s*';
56 |
57 | // parameter and value separator can have any number of spaces around itself
58 | $equalsSpaced = $space.$equals.$space;
59 | // lookahead test for space, closing tag, self-closing tag or end of string
60 | $empty = '(?=\s|'.$close.'|'.$slash.$space.$close.'|$)';
61 | // equals sign and alphanumeric value
62 | $simple = '((?:(?!=\s*|'.$close.'|'.$slash.$close.')[^\s])+)';
63 | // equals sign and value without unescaped string delimiters enclosed in them
64 | $complex = $string.'(?:[^'.$string.'\\\\]*(?:\\\\.[^'.$string.'\\\\]*)*)'.$string;
65 | // complete parameters matching regex
66 | $parameters = '(?(?:\s*(?:\w+(?:'.$equalsSpaced.$complex.'|'.$equalsSpaced.$simple.'|'.$empty.')))*)';
67 | // BBCode is the part after name that makes it behave like a non-empty parameter value
68 | $bbCode = '(?:'.$equals.$space.'(?'.$complex.'|'.$simple.'))?';
69 |
70 | // alphanumeric characters and dash
71 | $name = '(?'.static::buildNameRegex().')';
72 | // non-greedy match for any characters
73 | $content = '(?.*?)';
74 |
75 | // equal beginning for each variant: open tag, name and parameters
76 | $common = $open.$space.$name.$space.$bbCode.$space.$parameters.$space;
77 | // closing tag variants: just closing tag, self closing tag or content
78 | // and closing block with backreference name validation
79 | $justClosed = $close;
80 | $selfClosed = '(?'.$slash.')'.$space.$close;
81 | $withContent = $close.$content.$open.$space.'(?'.$slash.')'.$space.'(\k)'.$space.$close;
82 |
83 | return '(?:'.$common.'(?:'.$withContent.'|'.$justClosed.'|'.$selfClosed.'))';
84 | }
85 |
86 | /**
87 | * @param non-empty-string $text
88 | *
89 | * @return non-empty-string
90 | */
91 | private static function quote($text)
92 | {
93 | /** @var non-empty-string $quoted */
94 | $quoted = preg_replace('/(.)/us', '\\\\$0', $text);
95 |
96 | return $quoted;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/tests/AbstractTestCase.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | abstract class AbstractTestCase extends TestCase
10 | {
11 | public function willThrowException($exception)
12 | {
13 | version_compare(phpversion(), '7.0.0') > 0
14 | ? $this->expectException($exception)
15 | : $this->setExpectedException($exception);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/tests/EventsTest.php:
--------------------------------------------------------------------------------
1 |
18 | */
19 | final class EventsTest extends AbstractTestCase
20 | {
21 | public function testRaw()
22 | {
23 | $times = 0;
24 | $handlers = new HandlerContainer();
25 | $handlers->add('raw', function(ShortcodeInterface $s) { return $s->getContent(); });
26 | $handlers->add('n', function(ShortcodeInterface $s) use(&$times) { ++$times; return $s->getName(); });
27 | $handlers->add('c', function(ShortcodeInterface $s) use(&$times) { ++$times; return $s->getContent(); });
28 |
29 | $events = new EventContainer();
30 | $events->addListener(Events::FILTER_SHORTCODES, new FilterRawEventHandler(array('raw')));
31 |
32 | $processor = new Processor(new RegularParser(), $handlers);
33 | $processor = $processor->withEventContainer($events);
34 |
35 | $this->assertSame(' [n] [c]cnt[/c] [/n] ', $processor->process('[raw] [n] [c]cnt[/c] [/n] [/raw]'));
36 | $this->assertSame('x un [n] [c]cnt[/c] [/n] y', $processor->process('x [c]u[n][/c][raw] [n] [c]cnt[/c] [/n] [/raw] y'));
37 | $this->assertEquals(2, $times);
38 | }
39 |
40 | public function testStripContentOutsideShortcodes()
41 | {
42 | $handlers = new HandlerContainer();
43 | $handlers->add('name', function(ShortcodeInterface $s) { return $s->getName(); });
44 | $handlers->add('content', function(ShortcodeInterface $s) { return $s->getContent(); });
45 | $handlers->add('root', function(ProcessedShortcode $s) { return 'root['.$s->getContent().']'; });
46 |
47 | $events = new EventContainer();
48 | $events->addListener(Events::REPLACE_SHORTCODES, new ReplaceJoinEventHandler(array('root')));
49 |
50 | $processor = new Processor(new RegularParser(), $handlers);
51 | $processor = $processor->withEventContainer($events);
52 |
53 | $this->assertSame('a root[name name name] b', $processor->process('a [root]x [name] c[content] [name /] [/content] y[name/][/root] b'));
54 | }
55 |
56 | public function testDefaultApplier()
57 | {
58 | $handlers = new HandlerContainer();
59 | $handlers->add('name', function(ShortcodeInterface $s) { return $s->getName(); });
60 | $handlers->add('content', function(ShortcodeInterface $s) { return $s->getContent(); });
61 | $handlers->add('root', function(ProcessedShortcode $s) { return 'root['.$s->getContent().']'; });
62 |
63 | $events = new EventContainer();
64 | $events->addListener(Events::REPLACE_SHORTCODES, function(ReplaceShortcodesEvent $event) {
65 | $event->setResult(array_reduce(array_reverse($event->getReplacements()), function($state, ReplacedShortcode $r) {
66 | $offset = $r->getOffset();
67 | $length = mb_strlen($r->getText());
68 |
69 | return mb_substr($state, 0, $offset).$r->getReplacement().mb_substr($state, $offset + $length);
70 | }, $event->getText()));
71 | });
72 |
73 | $processor = new Processor(new RegularParser(), $handlers);
74 | $processor = $processor->withEventContainer($events);
75 |
76 | $this->assertSame('a root[x name c name y] b', $processor->process('a [root]x [name] c[content] [name /] [/content] y[/root] b'));
77 | }
78 |
79 | public function testExceptionOnHandlerForUnknownEvent()
80 | {
81 | $events = new EventContainer();
82 | $this->willThrowException('InvalidArgumentException');
83 | $events->addListener('invalid', function() {});
84 | }
85 |
86 | public function testInvalidFilterRawShortcodesNames()
87 | {
88 | $this->willThrowException('InvalidArgumentException');
89 | new FilterRawEventHandler(array(new \stdClass()));
90 | }
91 |
92 | public function testInvalidReplaceJoinNames()
93 | {
94 | $this->willThrowException('InvalidArgumentException');
95 | new ReplaceJoinEventHandler(array(new \stdClass()));
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/tests/FacadeTest.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | final class FacadeTest extends AbstractTestCase
17 | {
18 | public function testFacade()
19 | {
20 | $handlers = new HandlerContainer();
21 | $handlers
22 | ->add('name', function (ShortcodeInterface $s) { return $s->getName(); })
23 | ->addAlias('n', 'name');
24 |
25 | $facade = ShortcodeFacade::create($handlers, new CommonSyntax());
26 | $facade->addHandler('content', function (ShortcodeInterface $s) { return $s->getContent(); });
27 | $facade->addHandlerAlias('c', 'content');
28 | $facade->setParser(new RegexParser());
29 |
30 | $this->assertSame('n', $facade->process('[n]'));
31 | $this->assertSame('c', $facade->process('[c]c[/c]'));
32 |
33 | $shortcodes = $facade->parse('[b]');
34 | $this->assertInstanceOf('Thunder\\Shortcode\\Shortcode\\ParsedShortcodeInterface', $shortcodes[0]);
35 | }
36 |
37 | public function testFacadeEvents()
38 | {
39 | $facade = new ShortcodeFacade();
40 | $facade->addHandler('n', function (ShortcodeInterface $s) { return $s->getName(); });
41 | $facade->addEventHandler(Events::FILTER_SHORTCODES, new FilterRawEventHandler(array('raw')));
42 |
43 | $this->assertSame('[raw] [n] [/raw]', $facade->process('[raw] [n] [/raw]'));
44 | }
45 |
46 | public function testSerialization()
47 | {
48 | $facade = new ShortcodeFacade();
49 |
50 | $s = new Shortcode('c', array(), null);
51 | $this->assertSame('[c /]', $facade->serializeToText($s));
52 | $this->assertSame('c', $facade->unserializeFromText('[c]')->getName());
53 | $this->assertSame('[c /]', $facade->serialize($s, 'text'));
54 | $this->assertSame('c', $facade->unserialize('[c]', 'text')->getName());
55 |
56 | $json = '{"name":"c","parameters":[],"content":null,"bbCode":null}';
57 | $this->assertSame($json, $facade->serializeToJson($s));
58 | $this->assertSame('c', $facade->unserializeFromJson($json)->getName());
59 | $this->assertSame($json, $facade->serialize($s, 'json'));
60 | $this->assertSame('c', $facade->unserialize($json, 'json')->getName());
61 |
62 | $yaml = <<assertSame($yaml, $facade->serialize($s, 'yaml'));
70 | $this->assertSame('c', $facade->unserialize($yaml, 'yaml')->getName());
71 |
72 | $xml = <<
74 |
75 |
76 |
77 |
78 |
79 |
80 | EOF;
81 | $this->assertSame($xml, $facade->serialize($s, 'xml'));
82 | $this->assertSame('c', $facade->unserialize($xml, 'xml')->getName());
83 | }
84 |
85 | public function testInvalidSerializationFormatException()
86 | {
87 | $this->willThrowException('InvalidArgumentException');
88 | $facade = new ShortcodeFacade();
89 | $facade->serialize(new Shortcode('name', array(), null), 'invalid');
90 | }
91 |
92 | public function testInvalidUnserializationFormatException()
93 | {
94 | $this->willThrowException('InvalidArgumentException');
95 | $facade = new ShortcodeFacade();
96 | $facade->unserialize('[c]', 'invalid');
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/tests/Fake/ReverseShortcode.php:
--------------------------------------------------------------------------------
1 | getContent());
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/tests/HandlerContainerTest.php:
--------------------------------------------------------------------------------
1 |
10 | */
11 | final class HandlerContainerTest extends AbstractTestCase
12 | {
13 | public function testExceptionOnDuplicateHandler()
14 | {
15 | $handlers = new HandlerContainer();
16 | $handlers->add('name', function () {});
17 | $this->willThrowException('RuntimeException');
18 | $handlers->add('name', function () {});
19 | }
20 |
21 | public function testRemove()
22 | {
23 | $handlers = new HandlerContainer();
24 | static::assertFalse($handlers->has('code'));
25 | $handlers->add('code', function(ShortcodeInterface $s) {});
26 | static::assertTrue($handlers->has('code'));
27 | $handlers->remove('code');
28 | static::assertFalse($handlers->has('code'));
29 | }
30 |
31 | public function testRemoveException()
32 | {
33 | $handlers = new HandlerContainer();
34 | $this->willThrowException('RuntimeException');
35 | $handlers->remove('code');
36 | }
37 |
38 | public function testNames()
39 | {
40 | $handlers = new HandlerContainer();
41 | static::assertEmpty($handlers->getNames());
42 | $handlers->add('code', function(ShortcodeInterface $s) {});
43 | static::assertSame(array('code'), $handlers->getNames());
44 | $handlers->addAlias('c', 'code');
45 | static::assertSame(array('code', 'c'), $handlers->getNames());
46 | }
47 |
48 | public function testHandlerContainer()
49 | {
50 | $x = function () {};
51 |
52 | $handler = new HandlerContainer();
53 | $handler->add('x', $x);
54 | $handler->addAlias('y', 'x');
55 |
56 | static::assertSame($x, $handler->get('x'));
57 | }
58 |
59 | public function testInvalidHandler()
60 | {
61 | $handlers = new HandlerContainer();
62 | $this->willThrowException('RuntimeException');
63 | $handlers->add('invalid', new \stdClass());
64 | }
65 |
66 | public function testDefaultHandler()
67 | {
68 | $handlers = new HandlerContainer();
69 | static::assertNull($handlers->get('missing'));
70 |
71 | $handlers->setDefault(function () {});
72 | static::assertNotNull($handlers->get('missing'));
73 | }
74 |
75 | public function testExceptionIfAliasingNonExistentHandler()
76 | {
77 | $handlers = new HandlerContainer();
78 | $this->willThrowException('RuntimeException');
79 | $handlers->addAlias('m', 'missing');
80 | }
81 |
82 | public function testImmutableHandlerContainer()
83 | {
84 | $handlers = new HandlerContainer();
85 | $handlers->add('code', function () {});
86 | $handlers->addAlias('c', 'code');
87 | $imHandlers = new ImmutableHandlerContainer($handlers);
88 | $handlers->add('not', function() {});
89 |
90 | static::assertNull($imHandlers->get('missing'));
91 | static::assertNotNull($imHandlers->get('code'));
92 | static::assertNotNull($imHandlers->get('c'));
93 | static::assertNull($imHandlers->get('not'));
94 |
95 | $defaultHandlers = new HandlerContainer();
96 | $defaultHandlers->setDefault(function () {});
97 | $imDefaultHandlers = new ImmutableHandlerContainer($defaultHandlers);
98 | static::assertNotNull($imDefaultHandlers->get('missing'));
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/vendor/thunderer/shortcode/tests/SyntaxTest.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | final class SyntaxTest extends AbstractTestCase
13 | {
14 | /**
15 | * @dataProvider provideSyntaxes
16 | */
17 | public function testSyntax(SyntaxInterface $syntax, $open, $close, $slash, $parameter, $value)
18 | {
19 | static::assertSame($open, $syntax->getOpeningTag());
20 | static::assertSame($close, $syntax->getClosingTag());
21 | static::assertSame($slash, $syntax->getClosingTagMarker());
22 | static::assertSame($parameter, $syntax->getParameterValueSeparator());
23 | static::assertSame($value, $syntax->getParameterValueDelimiter());
24 | }
25 |
26 | public static function provideSyntaxes()
27 | {
28 | return array(
29 | array(new Syntax(), '[', ']', '/', '=', '"'),
30 | array(new Syntax('[[', ']]', '//', '==', '""'), '[[', ']]', '//', '==', '""'),
31 | array(new CommonSyntax(), '[', ']', '/', '=', '"'),
32 | );
33 | }
34 |
35 | /**
36 | * Note: do not merge this test with data provider above, code coverage
37 | * does not understand this and marks builder class as untested.
38 | */
39 | public function testBuilder()
40 | {
41 | $builder = new SyntaxBuilder();
42 | $this->testSyntax($builder->getSyntax(), '[', ']', '/', '=', '"');
43 |
44 | $builder = new SyntaxBuilder();
45 | $doubleBuiltSyntax = $builder
46 | ->setOpeningTag('[[')
47 | ->setClosingTag(']]')
48 | ->setClosingTagMarker('//')
49 | ->setParameterValueSeparator('==')
50 | ->setParameterValueDelimiter('""')
51 | ->getSyntax();
52 | $this->testSyntax($doubleBuiltSyntax, '[[', ']]', '//', '==', '""');
53 | }
54 | }
55 |
--------------------------------------------------------------------------------