From 2b218f607578f7476c8e7cea21a84eb3b4bf8e5f Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 10 May 2022 11:33:42 -0600 Subject: [PATCH 1/3] updated thunderer/shortcode --- composer.lock | 14 ++-- vendor/autoload.php | 7 +- vendor/composer/ClassLoader.php | 2 +- vendor/composer/InstalledVersions.php | 2 + vendor/composer/autoload_classmap.php | 2 +- vendor/composer/autoload_namespaces.php | 2 +- vendor/composer/autoload_psr4.php | 2 +- vendor/composer/autoload_real.php | 33 ++------ vendor/composer/autoload_static.php | 8 +- vendor/composer/installed.json | 16 ++-- vendor/composer/installed.php | 12 +-- .../shortcode/.github/workflows/test.yaml | 47 ++++++++++++ vendor/thunderer/shortcode/.gitignore | 2 + .../thunderer/shortcode/.symfony.insight.yaml | 4 - vendor/thunderer/shortcode/.travis.yml | 34 --------- vendor/thunderer/shortcode/LICENSE | 2 +- vendor/thunderer/shortcode/Makefile | 67 +++++++++++++--- vendor/thunderer/shortcode/README.md | 16 ++-- .../thunderer/shortcode/docker-compose.yaml | 30 ++++---- .../shortcode/docker/php-5.4/Dockerfile | 3 - .../shortcode/docker/php-5.x/Dockerfile | 11 +++ .../thunderer/shortcode/docker/php/Dockerfile | 12 +++ vendor/thunderer/shortcode/docker/php/php.ini | 1 + vendor/thunderer/shortcode/infection.json | 12 +++ vendor/thunderer/shortcode/phpunit.xml.dist | 22 +++--- vendor/thunderer/shortcode/psalm.xml | 19 +++++ .../src/Event/FilterShortcodesEvent.php | 20 ++++- .../src/Event/ReplaceShortcodesEvent.php | 25 +++++- .../src/EventContainer/EventContainer.php | 17 +++++ .../EventHandler/ReplaceJoinEventHandler.php | 3 +- vendor/thunderer/shortcode/src/Events.php | 1 + .../shortcode/src/Handler/DeclareHandler.php | 5 +- .../shortcode/src/Handler/EmailHandler.php | 2 +- .../src/Handler/PlaceholderHandler.php | 5 +- .../shortcode/src/Handler/UrlHandler.php | 2 +- .../shortcode/src/Handler/WrapHandler.php | 9 ++- .../src/HandlerContainer/HandlerContainer.php | 53 +++++++++++-- .../HandlerContainerInterface.php | 3 + .../ImmutableHandlerContainer.php | 9 +++ .../shortcode/src/Parser/RegexParser.php | 31 ++++++++ .../shortcode/src/Parser/RegularParser.php | 76 ++++++++++++++++--- .../shortcode/src/Parser/WordpressParser.php | 25 +++++- .../shortcode/src/Processor/Processor.php | 53 ++++++++++--- .../src/Processor/ProcessorContext.php | 37 ++++++++- .../src/Serializer/JsonSerializer.php | 3 + .../src/Serializer/SerializerInterface.php | 2 +- .../src/Serializer/TextSerializer.php | 16 +++- .../src/Serializer/XmlSerializer.php | 28 ++++++- .../src/Serializer/YamlSerializer.php | 5 +- .../src/Shortcode/AbstractShortcode.php | 26 +++++++ .../src/Shortcode/ParsedShortcode.php | 8 ++ .../src/Shortcode/ProcessedShortcode.php | 76 +++++++++++++------ .../src/Shortcode/ReplacedShortcode.php | 7 ++ .../shortcode/src/Shortcode/Shortcode.php | 9 +++ .../src/Shortcode/ShortcodeInterface.php | 3 +- .../shortcode/src/ShortcodeFacade.php | 75 ++++++++++++++++-- .../shortcode/src/Syntax/CommonSyntax.php | 5 ++ .../thunderer/shortcode/src/Syntax/Syntax.php | 17 +++++ .../shortcode/src/Syntax/SyntaxBuilder.php | 31 ++++++++ .../shortcode/src/Syntax/SyntaxInterface.php | 5 ++ .../src/Utility/RegexBuilderUtility.php | 10 +++ 61 files changed, 861 insertions(+), 223 deletions(-) create mode 100644 vendor/thunderer/shortcode/.github/workflows/test.yaml delete mode 100644 vendor/thunderer/shortcode/.symfony.insight.yaml delete mode 100644 vendor/thunderer/shortcode/.travis.yml delete mode 100644 vendor/thunderer/shortcode/docker/php-5.4/Dockerfile create mode 100644 vendor/thunderer/shortcode/docker/php-5.x/Dockerfile create mode 100644 vendor/thunderer/shortcode/docker/php/Dockerfile create mode 100644 vendor/thunderer/shortcode/docker/php/php.ini create mode 100644 vendor/thunderer/shortcode/infection.json create mode 100644 vendor/thunderer/shortcode/psalm.xml diff --git a/composer.lock b/composer.lock index 45e0cd3..40ab44d 100644 --- a/composer.lock +++ b/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "thunderer/shortcode", - "version": "v0.7.4", + "version": "v0.7.5", "source": { "type": "git", "url": "https://github.com/thunderer/Shortcode.git", - "reference": "79a219febd774ba1ee66a2992fee1145b4367561" + "reference": "a4fee30613bd46efb421f8305aff0466a3268a99" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thunderer/Shortcode/zipball/79a219febd774ba1ee66a2992fee1145b4367561", - "reference": "79a219febd774ba1ee66a2992fee1145b4367561", + "url": "https://api.github.com/repos/thunderer/Shortcode/zipball/a4fee30613bd46efb421f8305aff0466a3268a99", + "reference": "a4fee30613bd46efb421f8305aff0466a3268a99", "shasum": "" }, "require": { @@ -58,9 +58,9 @@ ], "support": { "issues": "https://github.com/thunderer/Shortcode/issues", - "source": "https://github.com/thunderer/Shortcode/tree/v0.7.4" + "source": "https://github.com/thunderer/Shortcode/tree/v0.7.5" }, - "time": "2020-03-08T11:25:13+00:00" + "time": "2022-01-13T18:53:33+00:00" } ], "packages-dev": [], @@ -76,5 +76,5 @@ "platform-overrides": { "php": "7.1.3" }, - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.3.0" } diff --git a/vendor/autoload.php b/vendor/autoload.php index 9860ba9..d7a4ef3 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -2,6 +2,11 @@ // autoload.php @generated by Composer +if (PHP_VERSION_ID < 50600) { + echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL; + exit(1); +} + require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInitd0b6ad2d0f2308b1099bc12e8c596f66::getLoader(); +return ComposerAutoloaderInit20dff4ef15e2090e54c04a9aa83321b9::getLoader(); diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index 0cd6055..afef3fa 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -149,7 +149,7 @@ public function getFallbackDirsPsr4() /** * @return string[] Array of classname => path - * @psalm-var array + * @psalm-return array */ public function getClassMap() { diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index d50e0c9..41bc143 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -21,6 +21,8 @@ * See also https://getcomposer.org/doc/07-runtime.md#installed-versions * * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final */ class InstalledVersions { diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 9923be8..84beac3 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -2,7 +2,7 @@ // autoload_classmap.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index b7fc012..15a2ff3 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -2,7 +2,7 @@ // autoload_namespaces.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index ee64f5c..e8e1e49 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -2,7 +2,7 @@ // autoload_psr4.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 23fee12..856afc5 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInitd0b6ad2d0f2308b1099bc12e8c596f66 +class ComposerAutoloaderInit20dff4ef15e2090e54c04a9aa83321b9 { private static $loader; @@ -24,31 +24,12 @@ public static function getLoader() require __DIR__ . '/platform_check.php'; - spl_autoload_register(array('ComposerAutoloaderInitd0b6ad2d0f2308b1099bc12e8c596f66', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); - spl_autoload_unregister(array('ComposerAutoloaderInitd0b6ad2d0f2308b1099bc12e8c596f66', 'loadClassLoader')); - - $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require __DIR__ . '/autoload_static.php'; - - call_user_func(\Composer\Autoload\ComposerStaticInitd0b6ad2d0f2308b1099bc12e8c596f66::getInitializer($loader)); - } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - } + spl_autoload_register(array('ComposerAutoloaderInit20dff4ef15e2090e54c04a9aa83321b9', 'loadClassLoader'), true, true); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); + spl_autoload_unregister(array('ComposerAutoloaderInit20dff4ef15e2090e54c04a9aa83321b9', 'loadClassLoader')); + + require __DIR__ . '/autoload_static.php'; + call_user_func(\Composer\Autoload\ComposerStaticInit20dff4ef15e2090e54c04a9aa83321b9::getInitializer($loader)); $loader->register(true); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 88e5c00..26843d1 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInitd0b6ad2d0f2308b1099bc12e8c596f66 +class ComposerStaticInit20dff4ef15e2090e54c04a9aa83321b9 { public static $prefixLengthsPsr4 = array ( 'T' => @@ -41,9 +41,9 @@ class ComposerStaticInitd0b6ad2d0f2308b1099bc12e8c596f66 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInitd0b6ad2d0f2308b1099bc12e8c596f66::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInitd0b6ad2d0f2308b1099bc12e8c596f66::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInitd0b6ad2d0f2308b1099bc12e8c596f66::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit20dff4ef15e2090e54c04a9aa83321b9::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit20dff4ef15e2090e54c04a9aa83321b9::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit20dff4ef15e2090e54c04a9aa83321b9::$classMap; }, null, ClassLoader::class); } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 7300359..a2b30f1 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -2,17 +2,17 @@ "packages": [ { "name": "thunderer/shortcode", - "version": "v0.7.4", - "version_normalized": "0.7.4.0", + "version": "v0.7.5", + "version_normalized": "0.7.5.0", "source": { "type": "git", "url": "https://github.com/thunderer/Shortcode.git", - "reference": "79a219febd774ba1ee66a2992fee1145b4367561" + "reference": "a4fee30613bd46efb421f8305aff0466a3268a99" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thunderer/Shortcode/zipball/79a219febd774ba1ee66a2992fee1145b4367561", - "reference": "79a219febd774ba1ee66a2992fee1145b4367561", + "url": "https://api.github.com/repos/thunderer/Shortcode/zipball/a4fee30613bd46efb421f8305aff0466a3268a99", + "reference": "a4fee30613bd46efb421f8305aff0466a3268a99", "shasum": "" }, "require": { @@ -27,7 +27,7 @@ "ext-json": "if you want to use JSON serializer", "symfony/yaml": "if you want to use YAML serializer" }, - "time": "2020-03-08T11:25:13+00:00", + "time": "2022-01-13T18:53:33+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -55,11 +55,11 @@ ], "support": { "issues": "https://github.com/thunderer/Shortcode/issues", - "source": "https://github.com/thunderer/Shortcode/tree/v0.7.4" + "source": "https://github.com/thunderer/Shortcode/tree/v0.7.5" }, "install-path": "../thunderer/shortcode" } ], - "dev": true, + "dev": false, "dev-package-names": [] } diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 40da702..864b723 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -5,9 +5,9 @@ 'type' => 'grav-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => '743c68a7a91d0805911497042bbecd9b1d75611d', + 'reference' => 'd351265e0de9dfd18dcc842977d80b97c9524e81', 'name' => 'getgrav/shortcode-core', - 'dev' => true, + 'dev' => false, ), 'versions' => array( 'getgrav/shortcode-core' => array( @@ -16,16 +16,16 @@ 'type' => 'grav-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => '743c68a7a91d0805911497042bbecd9b1d75611d', + 'reference' => 'd351265e0de9dfd18dcc842977d80b97c9524e81', 'dev_requirement' => false, ), 'thunderer/shortcode' => array( - 'pretty_version' => 'v0.7.4', - 'version' => '0.7.4.0', + 'pretty_version' => 'v0.7.5', + 'version' => '0.7.5.0', 'type' => 'library', 'install_path' => __DIR__ . '/../thunderer/shortcode', 'aliases' => array(), - 'reference' => '79a219febd774ba1ee66a2992fee1145b4367561', + 'reference' => 'a4fee30613bd46efb421f8305aff0466a3268a99', 'dev_requirement' => false, ), ), diff --git a/vendor/thunderer/shortcode/.github/workflows/test.yaml b/vendor/thunderer/shortcode/.github/workflows/test.yaml new file mode 100644 index 0000000..befc1ee --- /dev/null +++ b/vendor/thunderer/shortcode/.github/workflows/test.yaml @@ -0,0 +1,47 @@ +name: Test + +on: + push: + branches: ['master'] + pull_request: ~ + +jobs: + test: + runs-on: '${{ matrix.os }}' + strategy: + matrix: + php: ['5.3', '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] + os: ['ubuntu-latest'] + failure: [false] + include: + - { php: '8.2', os: 'ubuntu-latest', failure: true } # '8.2' means 'nightly' + steps: + - name: 'Checkout' + uses: 'actions/checkout@v2' + - name: 'Install PHP' + uses: 'shivammathur/setup-php@v2' + with: + php-version: '${{ matrix.php }}' + tools: 'composer:v2' + coverage: 'xdebug' + - name: 'PHP' + run: 'php -v' + + - name: 'Composer' + run: 'composer install' + continue-on-error: '${{ matrix.failure }}' + - name: 'PHPUnit' + run: 'php vendor/bin/phpunit --coverage-text' + continue-on-error: '${{ matrix.failure }}' + - name: 'Psalm' + run: | + composer require --dev vimeo/psalm + php vendor/bin/psalm --shepherd --php-version=${{ matrix.php }} + if: '${{ matrix.php >= 7.1 }}' + continue-on-error: '${{ matrix.failure }}' + - name: 'Infection' + run: | + composer require --dev --with-all-dependencies infection/infection + php vendor/bin/infection + if: '${{ matrix.php >= 7.1 }}' + continue-on-error: '${{ matrix.failure }}' diff --git a/vendor/thunderer/shortcode/.gitignore b/vendor/thunderer/shortcode/.gitignore index fcb35f8..34e595c 100644 --- a/vendor/thunderer/shortcode/.gitignore +++ b/vendor/thunderer/shortcode/.gitignore @@ -1,3 +1,5 @@ +.phpunit.result.cache +infection.log vendor composer.lock coverage diff --git a/vendor/thunderer/shortcode/.symfony.insight.yaml b/vendor/thunderer/shortcode/.symfony.insight.yaml deleted file mode 100644 index c165a42..0000000 --- a/vendor/thunderer/shortcode/.symfony.insight.yaml +++ /dev/null @@ -1,4 +0,0 @@ -rules: - # RegularParser::parse() disables xdebug.max_nesting_level to avoid errors when XDebug is enabled - php.dynamically_change_configuration: - enabled: false diff --git a/vendor/thunderer/shortcode/.travis.yml b/vendor/thunderer/shortcode/.travis.yml deleted file mode 100644 index e43287d..0000000 --- a/vendor/thunderer/shortcode/.travis.yml +++ /dev/null @@ -1,34 +0,0 @@ -dist: trusty -language: php - -php: - - 5.3 - - 5.4 - - 5.5 - - 5.6 - - 7.0 - - 7.1 - - 7.2 - - 7.3 - - 7.4snapshot - - hhvm - - nightly - -sudo: false - -before_script: - - COMPOSER_ROOT_VERSION=dev-master composer install - -script: - - vendor/bin/phpunit --coverage-text - -after_script: - - wget https://scrutinizer-ci.com/ocular.phar - - php ocular.phar code-coverage:upload --format=php-clover coverage.xml - -matrix: - allow_failures: - - php: 5.3 - - php: hhvm - - php: nightly - - php: hhvm diff --git a/vendor/thunderer/shortcode/LICENSE b/vendor/thunderer/shortcode/LICENSE index 778bd30..7410a25 100644 --- a/vendor/thunderer/shortcode/LICENSE +++ b/vendor/thunderer/shortcode/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015-2016 Tomasz Kowalczyk +Copyright (c) 2015-2022 Tomasz Kowalczyk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/thunderer/shortcode/Makefile b/vendor/thunderer/shortcode/Makefile index 6b23fcd..23bdc28 100644 --- a/vendor/thunderer/shortcode/Makefile +++ b/vendor/thunderer/shortcode/Makefile @@ -1,13 +1,60 @@ -PHP ?= 7.4 +PHP_VERSION ?= 8.0 +PHP := docker-compose run --rm php-${PHP_VERSION} +php-version: + ${PHP} php -v +cache-clear: + sudo rm -rfv coverage .phpunit.result.cache infection.log + +docker-build: + docker-compose build + +composer-install: + ${PHP} composer install +composer-self-update: + ${PHP} composer self-update composer-update: - docker-compose run --rm composer composer config platform.php ${PHP} - docker-compose run --rm composer composer update - docker-compose run --rm composer composer config --unset platform - -test: - docker-compose run --rm php-${PHP} php -v - docker-compose run --rm php-${PHP} php /app/vendor/bin/phpunit -c /app/phpunit.xml.dist -test-local: + ${PHP} composer update +composer-require: + ${PHP} composer require ${PACKAGE} +composer-require-dev: + ${PHP} composer require --dev ${PACKAGE} + +test: test-phpunit test-infection qa-psalm +test-phpunit: + ${PHP} php -v + ${PHP} php vendor/bin/phpunit --coverage-text +test-phpunit-local: php -v - php vendor/bin/phpunit + php vendor/bin/phpunit --coverage-text + php vendor/bin/psalm --no-cache + php vendor/bin/infection +test-infection: + ${PHP} php vendor/bin/infection -j2 --min-msi=80 + +travis: + # PHP_VERSION=5.3 make travis-job + PHP_VERSION=5.4 make travis-job + PHP_VERSION=5.5 make travis-job + PHP_VERSION=5.6 make travis-job + PHP_VERSION=7.0 make travis-job + PHP_VERSION=7.1 make travis-job + PHP_VERSION=7.2 make travis-job + PHP_VERSION=7.3 make travis-job + PHP_VERSION=7.4 make travis-job + PHP_VERSION=8.0 make travis-job +travis-job: + ${PHP} composer update --no-plugins + ${PHP} php -v + ${PHP} php vendor/bin/phpunit + if ${PHP} php -r 'exit((int)(version_compare(PHP_VERSION, "7.1", ">=") === false));'; then \ + ${PHP} composer require --dev vimeo/psalm infection/infection; \ + ${PHP} vendor/bin/psalm --threads=1 --no-cache --shepherd --find-unused-psalm-suppress; \ + ${PHP} vendor/bin/infection; \ + ${PHP} composer remove --dev vimeo/psalm infection/infection; \ + fi; + +qa-psalm: + ${PHP} php vendor/bin/psalm --no-cache +qa-psalm-suppressed: + grep -rn psalm-suppress src diff --git a/vendor/thunderer/shortcode/README.md b/vendor/thunderer/shortcode/README.md index bd77aac..071a377 100644 --- a/vendor/thunderer/shortcode/README.md +++ b/vendor/thunderer/shortcode/README.md @@ -1,14 +1,12 @@ # Shortcode -[![Build Status](https://travis-ci.org/thunderer/Shortcode.png?branch=master)](https://travis-ci.org/thunderer/Shortcode) -[![SensioLabsInsight](https://insight.sensiolabs.com/projects/5235d5e3-d112-48df-bc07-d4555aef293d/mini.png)](https://insight.sensiolabs.com/projects/5235d5e3-d112-48df-bc07-d4555aef293d) -[![License](https://poser.pugx.org/thunderer/shortcode/license.svg)](https://packagist.org/packages/thunderer/shortcode) +[![Build Status](https://github.com/thunderer/Shortcode/actions/workflows/test.yaml/badge.svg)](https://github.com/thunderer/Shortcode) [![Latest Stable Version](https://poser.pugx.org/thunderer/shortcode/v/stable.svg)](https://packagist.org/packages/thunderer/shortcode) [![Total Downloads](https://poser.pugx.org/thunderer/shortcode/downloads)](https://packagist.org/packages/thunderer/shortcode) -[![Dependency Status](https://www.versioneye.com/user/projects/551d5385971f7847ca000002/badge.svg)](https://www.versioneye.com/user/projects/551d5385971f7847ca000002) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/thunderer/Shortcode/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/thunderer/Shortcode/?branch=master) +[![License](https://poser.pugx.org/thunderer/shortcode/license.svg)](https://packagist.org/packages/thunderer/shortcode) +[![Psalm coverage](https://shepherd.dev/github/thunderer/Shortcode/coverage.svg)](https://shepherd.dev/github/thunderer/Shortcode) [![Code Coverage](https://scrutinizer-ci.com/g/thunderer/Shortcode/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/thunderer/Shortcode/?branch=master) -[![Code Climate](https://codeclimate.com/github/thunderer/Shortcode/badges/gpa.svg)](https://codeclimate.com/github/thunderer/Shortcode) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/thunderer/Shortcode/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/thunderer/Shortcode/?branch=master) Shortcode is a framework agnostic PHP library allowing to find, extract and process text fragments called "shortcodes" or "BBCodes". Examples of their usual syntax and usage are shown below: @@ -33,10 +31,10 @@ Each part is described in the dedicated section in this document. ## Installation -There are no required dependencies and all PHP versions from 5.3 up to latest 7.0 [are tested](https://travis-ci.org/thunderer/Shortcode) and supported. This library is available on Composer/Packagist as `thunderer/shortcode`, to install it execute: +There are no required dependencies and all PHP versions from 5.3 up to latest 8.1 [are tested](https://github.com/thunderer/Shortcode/actions/workflows/test.yaml) and supported. This library is available on Composer/Packagist as `thunderer/shortcode`, to install it execute: ``` -composer require thunderer/shortcode=^0.7.3 +composer require thunderer/shortcode=^0.7 ``` or manually update your `composer.json` with: @@ -44,7 +42,7 @@ or manually update your `composer.json` with: ``` (...) "require": { - "thunderer/shortcode": "^0.7.3" + "thunderer/shortcode": "^0.7" } (...) ``` diff --git a/vendor/thunderer/shortcode/docker-compose.yaml b/vendor/thunderer/shortcode/docker-compose.yaml index c03f8fd..5d6d75f 100644 --- a/vendor/thunderer/shortcode/docker-compose.yaml +++ b/vendor/thunderer/shortcode/docker-compose.yaml @@ -1,20 +1,20 @@ -version: '3' +version: '3.4' -services: - - composer: - image: 'composer:1.6' - volumes: ['.:/app'] +x-php: &php + volumes: ['.:/app', './docker/php/php.ini:/usr/local/etc/php/conf.d/php.ini'] + working_dir: '/app' +services: # PHP 5.3 contains neither mbstring extension nor docker-php-ext-install script # Original Dockerfile can be found here https://github.com/docker-library/php/pull/20/files # Unfortunately it fails to build now because GPG signatures do not exist anymore - # php-5.3: { build: 'docker/php-5.3', volumes: ['.:/app'] } - php-5.4: { build: 'docker/php-5.4', volumes: ['.:/app'] } - php-5.5: { image: 'php:5.5', volumes: ['.:/app'] } - php-5.6: { image: 'php:5.6', volumes: ['.:/app'] } - php-7.0: { image: 'php:7.0', volumes: ['.:/app'] } - php-7.1: { image: 'php:7.1', volumes: ['.:/app'] } - php-7.2: { image: 'php:7.2', volumes: ['.:/app'] } - php-7.3: { image: 'php:7.3', volumes: ['.:/app'] } - php-7.4: { image: 'php:7.4', volumes: ['.:/app'] } + # php-5.3: { build: { context: docker/php-5.x, args: { PHP_VERSION: 5.3 } } } + php-5.4: { <<: *php, build: { context: docker/php-5.x, args: { PHP_VERSION: 5.4 } } } + php-5.5: { <<: *php, build: { context: docker/php-5.x, args: { PHP_VERSION: 5.5 } } } + php-5.6: { <<: *php, build: { context: docker/php-5.x, args: { PHP_VERSION: 5.6 } } } + php-7.0: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 7.0 } } } + php-7.1: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 7.1.3 } } } + php-7.2: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 7.2 } } } + php-7.3: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 7.3 } } } + php-7.4: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 7.4 } } } + php-8.0: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 8.0 } } } diff --git a/vendor/thunderer/shortcode/docker/php-5.4/Dockerfile b/vendor/thunderer/shortcode/docker/php-5.4/Dockerfile deleted file mode 100644 index 187acb8..0000000 --- a/vendor/thunderer/shortcode/docker/php-5.4/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM php:5.4 - -RUN docker-php-ext-install mbstring \ No newline at end of file diff --git a/vendor/thunderer/shortcode/docker/php-5.x/Dockerfile b/vendor/thunderer/shortcode/docker/php-5.x/Dockerfile new file mode 100644 index 0000000..d3bf11b --- /dev/null +++ b/vendor/thunderer/shortcode/docker/php-5.x/Dockerfile @@ -0,0 +1,11 @@ +ARG PHP_VERSION=7.4 +FROM php:$PHP_VERSION + +RUN apt update && apt install -y --force-yes libonig-dev libzip-dev +RUN docker-php-ext-install mbstring zip + +RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ + && php -r "if (hash_file('sha384', 'composer-setup.php') === 'c31c1e292ad7be5f49291169c0ac8f683499edddcfd4e42232982d0fd193004208a58ff6f353fde0012d35fdd72bc394') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \ + && php composer-setup.php \ + && php -r "unlink('composer-setup.php');" \ + && mv composer.phar /usr/local/bin/composer diff --git a/vendor/thunderer/shortcode/docker/php/Dockerfile b/vendor/thunderer/shortcode/docker/php/Dockerfile new file mode 100644 index 0000000..1cc6625 --- /dev/null +++ b/vendor/thunderer/shortcode/docker/php/Dockerfile @@ -0,0 +1,12 @@ +ARG PHP_VERSION=8.0 +FROM php:$PHP_VERSION + +RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ + && php -r "if (hash_file('sha384', 'composer-setup.php') === '906a84df04cea2aa72f40b5f787e49f22d4c2f19492ac310e8cba5b96ac8b64115ac402c8cd292b8a03482574915d1a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \ + && php composer-setup.php \ + && php -r "unlink('composer-setup.php');" \ + && mv composer.phar /usr/local/bin/composer + +RUN apt update && apt install -y libonig-dev libzip-dev +RUN docker-php-ext-install mbstring zip +RUN pecl install xdebug && docker-php-ext-enable xdebug diff --git a/vendor/thunderer/shortcode/docker/php/php.ini b/vendor/thunderer/shortcode/docker/php/php.ini new file mode 100644 index 0000000..cea362e --- /dev/null +++ b/vendor/thunderer/shortcode/docker/php/php.ini @@ -0,0 +1 @@ +xdebug.mode=coverage diff --git a/vendor/thunderer/shortcode/infection.json b/vendor/thunderer/shortcode/infection.json new file mode 100644 index 0000000..ba36c9a --- /dev/null +++ b/vendor/thunderer/shortcode/infection.json @@ -0,0 +1,12 @@ +{ + "source": { + "directories": ["src"] + }, + "logs": { + "text": "infection.log" + }, + "timeout": 2, + "mutators": { + "@default": true + } +} diff --git a/vendor/thunderer/shortcode/phpunit.xml.dist b/vendor/thunderer/shortcode/phpunit.xml.dist index 9954ada..f7c807d 100644 --- a/vendor/thunderer/shortcode/phpunit.xml.dist +++ b/vendor/thunderer/shortcode/phpunit.xml.dist @@ -9,22 +9,22 @@ processIsolation = "false" stopOnFailure = "false" bootstrap = "vendor/autoload.php" - > + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"> - ./tests/ + tests - - - - + + + src + + + + + - - - ./src - - diff --git a/vendor/thunderer/shortcode/psalm.xml b/vendor/thunderer/shortcode/psalm.xml new file mode 100644 index 0000000..e35b9ed --- /dev/null +++ b/vendor/thunderer/shortcode/psalm.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + diff --git a/vendor/thunderer/shortcode/src/Event/FilterShortcodesEvent.php b/vendor/thunderer/shortcode/src/Event/FilterShortcodesEvent.php index c6559d6..dc554e3 100644 --- a/vendor/thunderer/shortcode/src/Event/FilterShortcodesEvent.php +++ b/vendor/thunderer/shortcode/src/Event/FilterShortcodesEvent.php @@ -13,28 +13,35 @@ */ class FilterShortcodesEvent { + /** @var ProcessedShortcode|null */ private $parent; - private $shortcodes; + /** @var ParsedShortcodeInterface[] */ + private $shortcodes = array(); + /** @param ParsedShortcodeInterface[] $shortcodes */ public function __construct(array $shortcodes, ProcessedShortcode $parent = null) { $this->parent = $parent; $this->setShortcodes($shortcodes); } - /** - * @return ParsedShortcodeInterface[] - */ + /** @return ParsedShortcodeInterface[] */ public function getShortcodes() { return $this->shortcodes; } + /** @return ProcessedShortcode|null */ public function getParent() { return $this->parent; } + /** + * @param ParsedShortcodeInterface[] $shortcodes + * + * @return void + */ public function setShortcodes(array $shortcodes) { $this->shortcodes = array(); @@ -43,6 +50,11 @@ public function setShortcodes(array $shortcodes) } } + /** + * @param ParsedShortcodeInterface $shortcode + * + * @return void + */ private function addShortcode(ParsedShortcodeInterface $shortcode) { $this->shortcodes[] = $shortcode; diff --git a/vendor/thunderer/shortcode/src/Event/ReplaceShortcodesEvent.php b/vendor/thunderer/shortcode/src/Event/ReplaceShortcodesEvent.php index 523a9d9..39e1827 100644 --- a/vendor/thunderer/shortcode/src/Event/ReplaceShortcodesEvent.php +++ b/vendor/thunderer/shortcode/src/Event/ReplaceShortcodesEvent.php @@ -13,12 +13,19 @@ */ class ReplaceShortcodesEvent { + /** @var ShortcodeInterface|null */ private $shortcode; + /** @var string */ private $text; /** @var ReplacedShortcode[] */ - private $replacements; + private $replacements = array(); + /** @var string|null */ private $result; + /** + * @param string $text + * @param ReplacedShortcode[] $replacements + */ public function __construct($text, array $replacements, ShortcodeInterface $shortcode = null) { $this->shortcode = $shortcode; @@ -27,6 +34,11 @@ public function __construct($text, array $replacements, ShortcodeInterface $shor $this->setReplacements($replacements); } + /** + * @param ReplacedShortcode[] $replacements + * + * @return void + */ private function setReplacements(array $replacements) { foreach($replacements as $replacement) { @@ -34,36 +46,47 @@ private function setReplacements(array $replacements) } } + /** @return void */ private function addReplacement(ReplacedShortcode $replacement) { $this->replacements[] = $replacement; } + /** @return string */ public function getText() { return $this->text; } + /** @return ReplacedShortcode[] */ public function getReplacements() { return $this->replacements; } + /** @return ShortcodeInterface|null */ public function getShortcode() { return $this->shortcode; } + /** + * @param string $result + * + * @return void + */ public function setResult($result) { $this->result = $result; } + /** @return string|null */ public function getResult() { return $this->result; } + /** @return bool */ public function hasResult() { return null !== $this->result; diff --git a/vendor/thunderer/shortcode/src/EventContainer/EventContainer.php b/vendor/thunderer/shortcode/src/EventContainer/EventContainer.php index 484d76a..01b0d29 100644 --- a/vendor/thunderer/shortcode/src/EventContainer/EventContainer.php +++ b/vendor/thunderer/shortcode/src/EventContainer/EventContainer.php @@ -8,12 +8,19 @@ */ final class EventContainer implements EventContainerInterface { + /** @psalm-var array> */ private $listeners = array(); public function __construct() { } + /** + * @param string $event + * @param callable $handler + * + * @return void + */ public function addListener($event, $handler) { if(!\in_array($event, Events::getEvents(), true)) { @@ -27,11 +34,21 @@ public function addListener($event, $handler) $this->listeners[$event][] = $handler; } + /** + * @param string $event + * + * @psalm-return list + */ public function getListeners($event) { return $this->hasEvent($event) ? $this->listeners[$event] : array(); } + /** + * @param string $name + * + * @return bool + */ private function hasEvent($name) { return array_key_exists($name, $this->listeners); diff --git a/vendor/thunderer/shortcode/src/EventHandler/ReplaceJoinEventHandler.php b/vendor/thunderer/shortcode/src/EventHandler/ReplaceJoinEventHandler.php index bb5311a..96710b2 100644 --- a/vendor/thunderer/shortcode/src/EventHandler/ReplaceJoinEventHandler.php +++ b/vendor/thunderer/shortcode/src/EventHandler/ReplaceJoinEventHandler.php @@ -24,7 +24,8 @@ public function __construct(array $names) public function __invoke(ReplaceShortcodesEvent $event) { - if($event->getShortcode() && in_array($event->getShortcode()->getName(), $this->names)) { + $shortcode = $event->getShortcode(); + if($shortcode && in_array($shortcode->getName(), $this->names)) { $replaces = array(); foreach($event->getReplacements() as $r) { $replaces[] = $r->getReplacement(); diff --git a/vendor/thunderer/shortcode/src/Events.php b/vendor/thunderer/shortcode/src/Events.php index df6d451..7d7bafb 100644 --- a/vendor/thunderer/shortcode/src/Events.php +++ b/vendor/thunderer/shortcode/src/Events.php @@ -9,6 +9,7 @@ final class Events const FILTER_SHORTCODES = 'event.filter-shortcodes'; const REPLACE_SHORTCODES = 'event.replace-shortcodes'; + /** @return string[] */ public static function getEvents() { return array(static::FILTER_SHORTCODES, static::REPLACE_SHORTCODES); diff --git a/vendor/thunderer/shortcode/src/Handler/DeclareHandler.php b/vendor/thunderer/shortcode/src/Handler/DeclareHandler.php index 32f8486..f0c4314 100644 --- a/vendor/thunderer/shortcode/src/Handler/DeclareHandler.php +++ b/vendor/thunderer/shortcode/src/Handler/DeclareHandler.php @@ -11,8 +11,10 @@ final class DeclareHandler { /** @var HandlerContainer */ private $handlers; + /** @var string */ private $delimiter; + /** @param string $delimiter */ public function __construct(HandlerContainer $container, $delimiter = '%') { $this->handlers = $container; @@ -33,12 +35,13 @@ public function __invoke(ShortcodeInterface $shortcode) } $keys = array_keys($args); $name = array_shift($keys); - $content = $shortcode->getContent(); + $content = (string)$shortcode->getContent(); $delimiter = $this->delimiter; $this->handlers->add($name, function(ShortcodeInterface $shortcode) use($content, $delimiter) { $args = $shortcode->getParameters(); $keys = array_map(function($key) use($delimiter) { return $delimiter.$key.$delimiter; }, array_keys($args)); + /** @var string[] $values */ $values = array_values($args); return str_replace($keys, $values, $content); diff --git a/vendor/thunderer/shortcode/src/Handler/EmailHandler.php b/vendor/thunderer/shortcode/src/Handler/EmailHandler.php index edf64dd..0312e9b 100644 --- a/vendor/thunderer/shortcode/src/Handler/EmailHandler.php +++ b/vendor/thunderer/shortcode/src/Handler/EmailHandler.php @@ -22,6 +22,6 @@ public function __invoke(ShortcodeInterface $shortcode) $email = $shortcode->getBbCode() ?: $shortcode->getContent(); $content = $shortcode->getContent() === null ? $email : $shortcode->getContent(); - return ''.$content.''; + return ''.(string)$content.''; } } diff --git a/vendor/thunderer/shortcode/src/Handler/PlaceholderHandler.php b/vendor/thunderer/shortcode/src/Handler/PlaceholderHandler.php index efc5a65..4906f5e 100644 --- a/vendor/thunderer/shortcode/src/Handler/PlaceholderHandler.php +++ b/vendor/thunderer/shortcode/src/Handler/PlaceholderHandler.php @@ -8,8 +8,10 @@ */ final class PlaceholderHandler { + /** @var string */ private $delimiter; + /** @param string $delimiter */ public function __construct($delimiter = '%') { $this->delimiter = $delimiter; @@ -27,8 +29,9 @@ public function __invoke(ShortcodeInterface $shortcode) $args = $shortcode->getParameters(); $delimiter = $this->delimiter; $keys = array_map(function($key) use($delimiter) { return $delimiter.$key.$delimiter; }, array_keys($args)); + /** @var string[] $values */ $values = array_values($args); - return str_replace($keys, $values, $shortcode->getContent()); + return str_replace($keys, $values, (string)$shortcode->getContent()); } } diff --git a/vendor/thunderer/shortcode/src/Handler/UrlHandler.php b/vendor/thunderer/shortcode/src/Handler/UrlHandler.php index 8bd9495..27d02ce 100644 --- a/vendor/thunderer/shortcode/src/Handler/UrlHandler.php +++ b/vendor/thunderer/shortcode/src/Handler/UrlHandler.php @@ -21,6 +21,6 @@ public function __invoke(ShortcodeInterface $shortcode) { $url = $shortcode->getBbCode() ?: $shortcode->getContent(); - return ''.$shortcode->getContent().''; + return ''.(string)$shortcode->getContent().''; } } diff --git a/vendor/thunderer/shortcode/src/Handler/WrapHandler.php b/vendor/thunderer/shortcode/src/Handler/WrapHandler.php index 9859fa4..1185156 100644 --- a/vendor/thunderer/shortcode/src/Handler/WrapHandler.php +++ b/vendor/thunderer/shortcode/src/Handler/WrapHandler.php @@ -8,15 +8,22 @@ */ final class WrapHandler { + /** @var string */ private $before; + /** @var string */ private $after; + /** + * @param string $before + * @param string $after + */ public function __construct($before, $after) { $this->before = $before; $this->after = $after; } + /** @return self */ public static function createBold() { return new self('', ''); @@ -32,6 +39,6 @@ public static function createBold() */ public function __invoke(ShortcodeInterface $shortcode) { - return $this->before.$shortcode->getContent().$this->after; + return $this->before.(string)$shortcode->getContent().$this->after; } } diff --git a/vendor/thunderer/shortcode/src/HandlerContainer/HandlerContainer.php b/vendor/thunderer/shortcode/src/HandlerContainer/HandlerContainer.php index 8bd3eb8..881ee06 100644 --- a/vendor/thunderer/shortcode/src/HandlerContainer/HandlerContainer.php +++ b/vendor/thunderer/shortcode/src/HandlerContainer/HandlerContainer.php @@ -1,17 +1,25 @@ */ final class HandlerContainer implements HandlerContainerInterface { - /** @var callable[] */ + /** @psalm-var array */ private $handlers = array(); - - /** @var callable */ - private $default; - + /** @psalm-var (callable(ShortcodeInterface):string)|null */ + private $default = null; + + /** + * @param string $name + * @param callable $handler + * @psalm-param callable(ShortcodeInterface):string $handler + * + * @return $this + */ public function add($name, $handler) { $this->guardHandler($handler); @@ -26,6 +34,12 @@ public function add($name, $handler) return $this; } + /** + * @param string $alias + * @param string $name + * + * @return $this + */ public function addAlias($alias, $name) { if (false === $this->has($name)) { @@ -33,9 +47,15 @@ public function addAlias($alias, $name) throw new \RuntimeException(sprintf($msg, $alias, $name)); } + /** @psalm-suppress PossiblyNullArgument */ return $this->add($alias, $this->get($name)); } + /** + * @param string $name + * + * @return void + */ public function remove($name) { if (false === $this->has($name)) { @@ -46,6 +66,12 @@ public function remove($name) unset($this->handlers[$name]); } + /** + * @param callable $handler + * @psalm-param callable(ShortcodeInterface):string $handler + * + * @return $this + */ public function setDefault($handler) { $this->guardHandler($handler); @@ -55,21 +81,38 @@ public function setDefault($handler) return $this; } + /** @return string[] */ public function getNames() { return array_keys($this->handlers); } + /** + * @param string $name + * + * @return callable|null + * @psalm-return (callable(ShortcodeInterface):string)|null + */ public function get($name) { return $this->has($name) ? $this->handlers[$name] : $this->default; } + /** + * @param string $name + * + * @return bool + */ public function has($name) { return array_key_exists($name, $this->handlers); } + /** + * @param callable $handler + * + * @return void + */ private function guardHandler($handler) { if (!is_callable($handler)) { diff --git a/vendor/thunderer/shortcode/src/HandlerContainer/HandlerContainerInterface.php b/vendor/thunderer/shortcode/src/HandlerContainer/HandlerContainerInterface.php index f512765..80b11ec 100644 --- a/vendor/thunderer/shortcode/src/HandlerContainer/HandlerContainerInterface.php +++ b/vendor/thunderer/shortcode/src/HandlerContainer/HandlerContainerInterface.php @@ -1,6 +1,8 @@ */ @@ -13,6 +15,7 @@ interface HandlerContainerInterface * @param string $name Shortcode name * * @return callable|null + * @psalm-return (callable(ShortcodeInterface):string)|null */ public function get($name); } diff --git a/vendor/thunderer/shortcode/src/HandlerContainer/ImmutableHandlerContainer.php b/vendor/thunderer/shortcode/src/HandlerContainer/ImmutableHandlerContainer.php index b868318..cf1c4cd 100644 --- a/vendor/thunderer/shortcode/src/HandlerContainer/ImmutableHandlerContainer.php +++ b/vendor/thunderer/shortcode/src/HandlerContainer/ImmutableHandlerContainer.php @@ -1,11 +1,14 @@ */ final class ImmutableHandlerContainer implements HandlerContainerInterface { + /** @var HandlerContainer */ private $handlers; public function __construct(HandlerContainer $handlers) @@ -13,6 +16,12 @@ public function __construct(HandlerContainer $handlers) $this->handlers = clone $handlers; } + /** + * @param string $name + * + * @return callable|null + * @psalm-return (callable(ShortcodeInterface):string)|null + */ public function get($name) { return $this->handlers->get($name); diff --git a/vendor/thunderer/shortcode/src/Parser/RegexParser.php b/vendor/thunderer/shortcode/src/Parser/RegexParser.php index cb01d26..4a83b39 100644 --- a/vendor/thunderer/shortcode/src/Parser/RegexParser.php +++ b/vendor/thunderer/shortcode/src/Parser/RegexParser.php @@ -14,8 +14,11 @@ final class RegexParser implements ParserInterface { /** @var SyntaxInterface */ private $syntax; + /** @var string */ private $shortcodeRegex; + /** @var string */ private $singleShortcodeRegex; + /** @var string */ private $parametersRegex; public function __construct(SyntaxInterface $syntax = null) @@ -45,10 +48,17 @@ public function parse($text) return array_filter($shortcodes); } + /** + * @param string $text + * @param int $offset + * + * @return ParsedShortcode + */ private function parseSingle($text, $offset) { preg_match($this->singleShortcodeRegex, $text, $matches, PREG_OFFSET_CAPTURE); + /** @psalm-var array $matches */ $name = $matches['name'][0]; $parameters = isset($matches['parameters'][0]) ? $this->parseParameters($matches['parameters'][0]) : array(); $bbCode = isset($matches['bbCode'][0]) && $matches['bbCode'][1] !== -1 @@ -59,6 +69,11 @@ private function parseSingle($text, $offset) return new ParsedShortcode(new Shortcode($name, $parameters, $content, $bbCode), $text, $offset); } + /** + * @param string $text + * + * @psalm-return array + */ private function parseParameters($text) { preg_match_all($this->parametersRegex, $text, $argsMatches); @@ -66,6 +81,7 @@ private function parseParameters($text) // loop because PHP 5.3 can't handle $this properly and I want separate methods $return = array(); foreach ($argsMatches[1] as $item) { + /** @psalm-var array{0:string,1:string} $parts */ $parts = explode($this->syntax->getParameterValueSeparator(), $item, 2); $return[trim($parts[0])] = $this->parseValue(isset($parts[1]) ? $parts[1] : null); } @@ -73,11 +89,21 @@ private function parseParameters($text) return $return; } + /** + * @param string|null $value + * + * @return string|null + */ private function parseValue($value) { return null === $value ? null : $this->extractValue(trim($value)); } + /** + * @param string $value + * + * @return string + */ private function extractValue($value) { $length = strlen($this->syntax->getParameterValueDelimiter()); @@ -85,6 +111,11 @@ private function extractValue($value) return $this->isDelimitedValue($value) ? substr($value, $length, -1 * $length) : $value; } + /** + * @param string $value + * + * @return bool + */ private function isDelimitedValue($value) { return preg_match('/^'.$this->syntax->getParameterValueDelimiter().'/us', $value) diff --git a/vendor/thunderer/shortcode/src/Parser/RegularParser.php b/vendor/thunderer/shortcode/src/Parser/RegularParser.php index 22f4562..d46a36a 100644 --- a/vendor/thunderer/shortcode/src/Parser/RegularParser.php +++ b/vendor/thunderer/shortcode/src/Parser/RegularParser.php @@ -12,14 +12,20 @@ */ final class RegularParser implements ParserInterface { + /** @var string */ private $lexerRegex; + /** @var string */ private $nameRegex; - private $tokens; - private $tokensCount; - private $position; + /** @psalm-var list */ + private $tokens = array(); + /** @var int */ + private $tokensCount = 0; + /** @var int */ + private $position = 0; /** @var int[] */ - private $backtracks; - private $lastBacktrack; + private $backtracks = array(); + /** @var int */ + private $lastBacktrack = 0; const TOKEN_OPEN = 1; const TOKEN_CLOSE = 2; @@ -42,7 +48,7 @@ public function __construct(SyntaxInterface $syntax = null) */ public function parse($text) { - $nestingLevel = ini_set('xdebug.max_nesting_level', -1); + $nestingLevel = ini_set('xdebug.max_nesting_level', '-1'); $this->tokens = $this->tokenize($text); $this->backtracks = array(); $this->lastBacktrack = 0; @@ -73,6 +79,16 @@ public function parse($text) return $shortcodes; } + /** + * @param string $name + * @psalm-param array $parameters + * @param string|null $bbCode + * @param int $offset + * @param string|null $content + * @param string $text + * + * @return ParsedShortcode + */ private function getObject($name, $parameters, $bbCode, $offset, $content, $text) { return new ParsedShortcode(new Shortcode($name, $parameters, $content, $bbCode), $text, $offset); @@ -80,6 +96,14 @@ private function getObject($name, $parameters, $bbCode, $offset, $content, $text /* --- RULES ----------------------------------------------------------- */ + /** + * @param string[] $names + * @psalm-param list $names + * FIXME: investigate the reason Psalm complains about references + * @psalm-suppress ReferenceConstraintViolation + * + * @return ParsedShortcode[]|string|false + */ private function shortcode(array &$names) { if(!$this->match(self::TOKEN_OPEN, false)) { return false; } @@ -118,6 +142,7 @@ private function shortcode(array &$names) } $this->beginBacktrack(); + /** @psalm-suppress MixedArgumentTypeCoercion */ $contentMatchedShortcodes = $this->shortcode($names); if(\is_string($contentMatchedShortcodes)) { $closingName = $contentMatchedShortcodes; @@ -133,7 +158,6 @@ private function shortcode(array &$names) $this->beginBacktrack(); if(false !== ($closingName = $this->close($names))) { - if(null === $content) { $content = ''; } $this->backtrack(); $shortcodes = array(); break; @@ -167,6 +191,11 @@ private function shortcode(array &$names) return array($this->getObject($name, $parameters, $bbCode, $offset, $content, $this->getBacktrack())); } + /** + * @param string[] $names + * + * @return string|false + */ private function close(array &$names) { if(!$this->match(self::TOKEN_OPEN, true)) { return false; } @@ -177,6 +206,7 @@ private function close(array &$names) return \in_array($closingName, $names, true) ? $closingName : false; } + /** @psalm-return array|false */ private function parameters() { $parameters = array(); @@ -195,6 +225,7 @@ private function parameters() return $parameters; } + /** @return false|string */ private function value() { $value = ''; @@ -221,12 +252,14 @@ private function value() /* --- PARSER ---------------------------------------------------------- */ + /** @return void */ private function beginBacktrack() { $this->backtracks[] = $this->position; $this->lastBacktrack = $this->position; } + /** @return string */ private function getBacktrack() { $position = array_pop($this->backtracks); @@ -238,6 +271,11 @@ private function getBacktrack() return $backtrack; } + /** + * @param bool $modifyPosition + * + * @return string + */ private function backtrack($modifyPosition = true) { $position = array_pop($this->backtracks); @@ -254,11 +292,22 @@ private function backtrack($modifyPosition = true) return $backtrack; } + /** + * @param int $type + * + * @return bool + */ private function lookahead($type) { return $this->position < $this->tokensCount && $this->tokens[$this->position][0] === $type; } + /** + * @param int|null $type + * @param bool $ws + * + * @return string + */ private function match($type, $ws) { if($this->position >= $this->tokensCount) { @@ -280,6 +329,11 @@ private function match($type, $ws) /* --- LEXER ----------------------------------------------------------- */ + /** + * @param string $text + * + * @psalm-return list + */ private function tokenize($text) { $count = preg_match_all($this->lexerRegex, $text, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE); @@ -308,13 +362,17 @@ private function tokenize($text) return $tokens; } + /** @return string */ private function prepareLexer(SyntaxInterface $syntax) { + // FIXME: for some reason Psalm does not understand the `@psalm-var callable() $var` annotation + /** @psalm-suppress MissingClosureParamType, MissingClosureReturnType */ $group = function($text, $group) { - return '(?<'.$group.'>'.preg_replace('/(.)/us', '\\\\$0', $text).')'; + return '(?<'.(string)$group.'>'.preg_replace('/(.)/us', '\\\\$0', (string)$text).')'; }; + /** @psalm-suppress MissingClosureParamType, MissingClosureReturnType */ $quote = function($text) { - return preg_replace('/(.)/us', '\\\\$0', $text); + return preg_replace('/(.)/us', '\\\\$0', (string)$text); }; $rules = array( diff --git a/vendor/thunderer/shortcode/src/Parser/WordpressParser.php b/vendor/thunderer/shortcode/src/Parser/WordpressParser.php index a579e6b..03a4611 100644 --- a/vendor/thunderer/shortcode/src/Parser/WordpressParser.php +++ b/vendor/thunderer/shortcode/src/Parser/WordpressParser.php @@ -26,21 +26,33 @@ */ final class WordpressParser implements ParserInterface { + /** @var string */ private static $shortcodeRegex = '/\\[(\\[?)()(?![\\w-])([^\\]\\/]*(?:\\/(?!\\])[^\\]\\/]*)*?)(?:(\\/)\\]|\\](?:([^\\[]*+(?:\\[(?!\\/\\2\\])[^\\[]*+)*+)\\[\\/\\2\\])?)(\\]?)/s'; + /** @var string */ private static $argumentsRegex = '/([\w-]+)\s*=\s*"([^"]*)"(?:\s|$)|([\w-]+)\s*=\s*\'([^\']*)\'(?:\s|$)|([\w-]+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/'; - private $names; + /** @var string[] */ + private $names = array(); - /* private function __construct() {} */ + public function __construct() + { + } + /** @return self */ public static function createFromHandlers(HandlerContainer $handlers) { return static::createFromNames($handlers->getNames()); } + /** + * @param string[] $names + * + * @return self + */ public static function createFromNames(array $names) { foreach($names as $name) { + /** @psalm-suppress DocblockTypeContradiction, RedundantConditionGivenDocblockType */ if(false === is_string($name)) { throw new \InvalidArgumentException('Shortcode name must be a string!'); } @@ -60,7 +72,7 @@ public static function createFromNames(array $names) public function parse($text) { $names = $this->names - ? implode('|', array_map('preg_quote', $this->names)) + ? implode('|', array_map(function($name) { return preg_quote($name, '/'); }, $this->names)) : RegexBuilderUtility::buildNameRegex(); $regex = str_replace('', $names, static::$shortcodeRegex); preg_match_all($regex, $text, $matches, PREG_OFFSET_CAPTURE); @@ -81,6 +93,11 @@ public function parse($text) return $shortcodes; } + /** + * @param string $text + * + * @psalm-return array + */ private static function parseParameters($text) { $text = preg_replace('/[\x{00a0}\x{200b}]+/u', ' ', $text); @@ -105,6 +122,8 @@ private static function parseParameters($text) } foreach($parameters as $key => $value) { + // NOTE: the `?: ''` fallback is the only change from the way WordPress parses shortcodes to satisfy Psalm's PossiblyNullArgument + $value = $value ?: ''; if(false !== strpos($value, '<') && 1 !== preg_match('/^[^<]*+(?:<[^>]*+>[^<]*+)*+$/', $value)) { $parameters[$key] = ''; } diff --git a/vendor/thunderer/shortcode/src/Processor/Processor.php b/vendor/thunderer/shortcode/src/Processor/Processor.php index d20fd13..e3e5745 100644 --- a/vendor/thunderer/shortcode/src/Processor/Processor.php +++ b/vendor/thunderer/shortcode/src/Processor/Processor.php @@ -10,6 +10,7 @@ use Thunder\Shortcode\Shortcode\ReplacedShortcode; use Thunder\Shortcode\Shortcode\ParsedShortcodeInterface; use Thunder\Shortcode\Shortcode\ProcessedShortcode; +use Thunder\Shortcode\Shortcode\ShortcodeInterface; /** * @author Tomasz Kowalczyk @@ -20,12 +21,14 @@ final class Processor implements ProcessorInterface private $handlers; /** @var ParserInterface */ private $parser; - /** @var EventContainerInterface */ + /** @var EventContainerInterface|null */ private $eventContainer; /** @var int|null */ private $recursionDepth; // infinite recursion + /** @var int|null */ private $maxIterations = 1; // one iteration + /** @var bool */ private $autoProcessContent = true; // automatically process shortcode content public function __construct(ParserInterface $parser, Handlers $handlers) @@ -61,6 +64,12 @@ public function process($text) return $text; } + /** + * @param string $name + * @param object $event + * + * @return object + */ private function dispatchEvent($name, $event) { if(null === $this->eventContainer) { @@ -75,6 +84,11 @@ private function dispatchEvent($name, $event) return $event; } + /** + * @param string $text + * + * @return string + */ private function processIteration($text, ProcessorContext $context, ProcessedShortcode $parent = null) { if (null !== $this->recursionDepth && $context->recursionLevel > $this->recursionDepth) { @@ -88,7 +102,7 @@ private function processIteration($text, ProcessorContext $context, ProcessedSho $shortcodes = $filterEvent->getShortcodes(); $replaces = array(); $baseOffset = $parent && $shortcodes - ? mb_strpos($parent->getShortcodeText(), $shortcodes[0]->getText(), null, 'utf-8') - $shortcodes[0]->getOffset() + $parent->getOffset() + ? (int)mb_strpos($parent->getShortcodeText(), $shortcodes[0]->getText(), 0, 'utf-8') - $shortcodes[0]->getOffset() + $parent->getOffset() : 0; foreach ($shortcodes as $shortcode) { $name = $shortcode->getName(); @@ -100,7 +114,7 @@ private function processIteration($text, ProcessorContext $context, ProcessedSho $context->shortcodeText = $shortcode->getText(); $context->offset = $shortcode->getOffset(); $context->shortcode = $shortcode; - $context->textContent = $shortcode->getContent(); + $context->textContent = (string)$shortcode->getContent(); $handler = $this->handlers->get($name); $replace = $this->processHandler($shortcode, $context, $handler); @@ -111,12 +125,17 @@ private function processIteration($text, ProcessorContext $context, ProcessedSho $applyEvent = new ReplaceShortcodesEvent($text, $replaces, $parent); $this->dispatchEvent(Events::REPLACE_SHORTCODES, $applyEvent); - return $applyEvent->hasResult() ? $applyEvent->getResult() : $this->applyReplaces($text, $replaces); + return $applyEvent->hasResult() ? (string)$applyEvent->getResult() : $this->applyReplaces($text, $replaces); } + /** + * @param string $text + * @param ReplacedShortcode[] $replaces + * + * @return string + */ private function applyReplaces($text, array $replaces) { - /** @var ReplacedShortcode $s */ foreach(array_reverse($replaces) as $s) { $offset = $s->getOffset(); $length = mb_strlen($s->getText(), 'utf-8'); @@ -128,6 +147,10 @@ private function applyReplaces($text, array $replaces) return $text; } + /** + * @psalm-param (callable(ShortcodeInterface):string)|null $handler + * @return string + */ private function processHandler(ParsedShortcodeInterface $parsed, ProcessorContext $context, $handler) { $processed = ProcessedShortcode::createFromContext(clone $context); @@ -139,24 +162,27 @@ private function processHandler(ParsedShortcodeInterface $parsed, ProcessorConte } $state = $parsed->getText(); - $length = mb_strlen($processed->getTextContent(), 'utf-8'); - $offset = mb_strrpos($state, $processed->getTextContent(), 0, 'utf-8'); + /** @psalm-suppress RedundantCast */ + $length = (int)mb_strlen($processed->getTextContent(), 'utf-8'); + $offset = (int)mb_strrpos($state, $processed->getTextContent(), 0, 'utf-8'); - return mb_substr($state, 0, $offset, 'utf-8').$processed->getContent().mb_substr($state, $offset + $length, mb_strlen($state, 'utf-8'), 'utf-8'); + return mb_substr($state, 0, $offset, 'utf-8').(string)$processed->getContent().mb_substr($state, $offset + $length, mb_strlen($state, 'utf-8'), 'utf-8'); } + /** @return string|null */ private function processRecursion(ProcessedShortcode $shortcode, ProcessorContext $context) { - if ($this->autoProcessContent && null !== $shortcode->getContent()) { + $content = $shortcode->getContent(); + if ($this->autoProcessContent && null !== $content) { $context->recursionLevel++; // this is safe from using max iterations value because it's manipulated in process() method - $content = $this->processIteration($shortcode->getContent(), clone $context, $shortcode); + $content = $this->processIteration($content, clone $context, $shortcode); $context->recursionLevel--; return $content; } - return $shortcode->getContent(); + return $content; } /** @@ -185,6 +211,7 @@ public function withEventContainer(EventContainerInterface $eventContainer) */ public function withRecursionDepth($depth) { + /** @psalm-suppress DocblockTypeContradiction */ if (null !== $depth && !(is_int($depth) && $depth >= 0)) { $msg = 'Recursion depth must be null (infinite) or integer >= 0!'; throw new \InvalidArgumentException($msg); @@ -208,6 +235,7 @@ public function withRecursionDepth($depth) */ public function withMaxIterations($iterations) { + /** @psalm-suppress DocblockTypeContradiction */ if (null !== $iterations && !(is_int($iterations) && $iterations > 0)) { $msg = 'Maximum number of iterations must be null (infinite) or integer > 0!'; throw new \InvalidArgumentException($msg); @@ -230,13 +258,14 @@ public function withMaxIterations($iterations) */ public function withAutoProcessContent($flag) { + /** @psalm-suppress DocblockTypeContradiction */ if (!is_bool($flag)) { $msg = 'Auto processing flag must be a boolean value!'; throw new \InvalidArgumentException($msg); } $self = clone $this; - $self->autoProcessContent = (bool)$flag; + $self->autoProcessContent = $flag; return $self; } diff --git a/vendor/thunderer/shortcode/src/Processor/ProcessorContext.php b/vendor/thunderer/shortcode/src/Processor/ProcessorContext.php index c75eed6..f9e8c6c 100644 --- a/vendor/thunderer/shortcode/src/Processor/ProcessorContext.php +++ b/vendor/thunderer/shortcode/src/Processor/ProcessorContext.php @@ -1,6 +1,7 @@ */ public $namePosition = array(); + /** @var string */ public $text = ''; + /** @var string */ public $shortcodeText = ''; + /** @var int */ public $iterationNumber = 0; + /** @var int */ public $recursionLevel = 0; + /** + * @var int + * @psalm-suppress PropertyNotSetInConstructor + */ public $offset; + /** + * @var int + * @psalm-suppress PropertyNotSetInConstructor + */ public $baseOffset; + + public function __construct() + { + } } diff --git a/vendor/thunderer/shortcode/src/Serializer/JsonSerializer.php b/vendor/thunderer/shortcode/src/Serializer/JsonSerializer.php index 2530306..6ee6447 100644 --- a/vendor/thunderer/shortcode/src/Serializer/JsonSerializer.php +++ b/vendor/thunderer/shortcode/src/Serializer/JsonSerializer.php @@ -26,6 +26,7 @@ public function serialize(ShortcodeInterface $shortcode) */ public function unserialize($text) { + /** @psalm-var array{name:string,parameters:array,bbCode:string|null,content:string|null}|null $data */ $data = json_decode($text, true); if (!is_array($data)) { @@ -35,11 +36,13 @@ public function unserialize($text) throw new \InvalidArgumentException('Malformed Shortcode JSON, expected name, parameters, and content!'); } + /** @var string $name */ $name = array_key_exists('name', $data) ? $data['name'] : null; $parameters = array_key_exists('parameters', $data) ? $data['parameters'] : array(); $content = array_key_exists('content', $data) ? $data['content'] : null; $bbCode = array_key_exists('bbCode', $data) ? $data['bbCode'] : null; + /** @psalm-suppress DocblockTypeContradiction */ if(!is_array($parameters)) { throw new \InvalidArgumentException('Parameters must be an array!'); } diff --git a/vendor/thunderer/shortcode/src/Serializer/SerializerInterface.php b/vendor/thunderer/shortcode/src/Serializer/SerializerInterface.php index bf61d72..7f50f9e 100644 --- a/vendor/thunderer/shortcode/src/Serializer/SerializerInterface.php +++ b/vendor/thunderer/shortcode/src/Serializer/SerializerInterface.php @@ -20,7 +20,7 @@ public function serialize(ShortcodeInterface $shortcode); /** * Loads back Shortcode instance from serialized format * - * @param $text + * @param string $text * * @return ShortcodeInterface */ diff --git a/vendor/thunderer/shortcode/src/Serializer/TextSerializer.php b/vendor/thunderer/shortcode/src/Serializer/TextSerializer.php index 1832962..7d93acf 100644 --- a/vendor/thunderer/shortcode/src/Serializer/TextSerializer.php +++ b/vendor/thunderer/shortcode/src/Serializer/TextSerializer.php @@ -12,6 +12,7 @@ */ final class TextSerializer implements SerializerInterface { + /** @var SyntaxInterface */ private $syntax; public function __construct(SyntaxInterface $syntax = null) @@ -19,6 +20,7 @@ public function __construct(SyntaxInterface $syntax = null) $this->syntax = $syntax ?: new Syntax(); } + /** @inheritDoc */ public function serialize(ShortcodeInterface $shortcode) { $open = $this->syntax->getOpeningTag(); @@ -33,9 +35,14 @@ public function serialize(ShortcodeInterface $shortcode) return null === $shortcode->getContent() ? $return.' '.$marker.$close - : $return.$close.$shortcode->getContent().$open.$marker.$shortcode->getName().$close; + : $return.$close.(string)$shortcode->getContent().$open.$marker.$shortcode->getName().$close; } + /** + * @psalm-param array $parameters + * + * @return string + */ private function serializeParameters(array $parameters) { // unfortunately array_reduce() does not support keys @@ -47,6 +54,11 @@ private function serializeParameters(array $parameters) return $return; } + /** + * @param string|null $value + * + * @return string + */ private function serializeValue($value) { if (null === $value) { @@ -76,7 +88,7 @@ public function unserialize($text) throw new \InvalidArgumentException(sprintf($msg, $text)); } - /** @var $parsed ShortcodeInterface */ + /** @var ShortcodeInterface $parsed */ $parsed = array_shift($shortcodes); $name = $parsed->getName(); diff --git a/vendor/thunderer/shortcode/src/Serializer/XmlSerializer.php b/vendor/thunderer/shortcode/src/Serializer/XmlSerializer.php index fa8f568..a2af59e 100644 --- a/vendor/thunderer/shortcode/src/Serializer/XmlSerializer.php +++ b/vendor/thunderer/shortcode/src/Serializer/XmlSerializer.php @@ -50,6 +50,13 @@ public function serialize(ShortcodeInterface $shortcode) return $doc->saveXML(); } + /** + * @param \DOMDocument $doc + * @param string $name + * @param string|null $content + * + * @return \DOMElement + */ private function createCDataNode(\DOMDocument $doc, $name, $content) { $node = $doc->createElement($name); @@ -70,7 +77,7 @@ public function unserialize($text) { $xml = new \DOMDocument(); $internalErrors = libxml_use_internal_errors(true); - if(!$text || ($text && !$xml->loadXML($text))) { + if(!$text || !$xml->loadXML($text)) { libxml_use_internal_errors($internalErrors); throw new \InvalidArgumentException('Failed to parse provided XML!'); } @@ -97,6 +104,11 @@ public function unserialize($text) return new Shortcode($name, $parameters, $content, $bbCode); } + /** + * @param \DOMNodeList $node + * + * @return string|null + */ private function getValue(\DOMNodeList $node) { return $node->length === 1 && $node->item(0)->hasChildNodes() @@ -104,11 +116,23 @@ private function getValue(\DOMNodeList $node) : null; } + /** + * @param \DOMNode $node + * @param string $name + * @psalm-suppress UnusedParam + * + * @return string + */ private function getAttribute(\DOMNode $node, $name) { + /** + * @var \DOMNode $attribute + * @psalm-suppress NullReference + */ $attribute = $node->attributes->getNamedItem($name); - if(!$attribute || ($attribute && !$attribute->nodeValue)) { + /** @psalm-suppress DocblockTypeContradiction */ + if(!$attribute || !$attribute->nodeValue) { throw new \InvalidArgumentException('Invalid shortcode XML!'); } diff --git a/vendor/thunderer/shortcode/src/Serializer/YamlSerializer.php b/vendor/thunderer/shortcode/src/Serializer/YamlSerializer.php index c6c4023..b890af1 100644 --- a/vendor/thunderer/shortcode/src/Serializer/YamlSerializer.php +++ b/vendor/thunderer/shortcode/src/Serializer/YamlSerializer.php @@ -27,20 +27,23 @@ public function serialize(ShortcodeInterface $shortcode) */ public function unserialize($text) { + /** @psalm-var array{name:string,parameters:array,bbCode:string|null,content:string|null}|null $data */ $data = Yaml::parse($text); - if(!$data || !is_array($data)) { + if(!is_array($data)) { throw new \InvalidArgumentException('Invalid YAML, cannot unserialize Shortcode!'); } if (!array_intersect(array_keys($data), array('name', 'parameters', 'content'))) { throw new \InvalidArgumentException('Malformed shortcode YAML, expected name, parameters, and content!'); } + /** @var string $name */ $name = array_key_exists('name', $data) ? $data['name'] : null; $parameters = array_key_exists('parameters', $data) ? $data['parameters'] : array(); $content = array_key_exists('content', $data) ? $data['content'] : null; $bbCode = array_key_exists('bbCode', $data) ? $data['bbCode'] : null; + /** @psalm-suppress DocblockTypeContradiction */ if(!is_array($parameters)) { throw new \InvalidArgumentException('Parameters must be an array!'); } diff --git a/vendor/thunderer/shortcode/src/Shortcode/AbstractShortcode.php b/vendor/thunderer/shortcode/src/Shortcode/AbstractShortcode.php index 2f410b1..a09ed8f 100644 --- a/vendor/thunderer/shortcode/src/Shortcode/AbstractShortcode.php +++ b/vendor/thunderer/shortcode/src/Shortcode/AbstractShortcode.php @@ -6,41 +6,65 @@ */ abstract class AbstractShortcode { + /** @var string */ protected $name; + /** @psalm-var array */ protected $parameters = array(); + /** @var string|null */ protected $content; + /** @var string|null */ protected $bbCode; + /** @return bool */ public function hasContent() { return $this->content !== null; } + /** @return string */ public function getName() { return $this->name; } + /** @psalm-return array */ public function getParameters() { return $this->parameters; } + /** + * @param string $name + * + * @return bool + */ public function hasParameter($name) { return array_key_exists($name, $this->parameters); } + /** @return bool */ public function hasParameters() { return (bool)$this->parameters; } + /** + * @param string $name + * @param string|null $default + * + * @psalm-return string|null + */ public function getParameter($name, $default = null) { return $this->hasParameter($name) ? $this->parameters[$name] : $default; } + /** + * @param int $index + * + * @return string|null + */ public function getParameterAt($index) { $keys = array_keys($this->parameters); @@ -48,11 +72,13 @@ public function getParameterAt($index) return array_key_exists($index, $keys) ? $keys[$index] : null; } + /** @return string|null */ public function getContent() { return $this->content; } + /** @return string|null */ public function getBbCode() { return $this->bbCode; diff --git a/vendor/thunderer/shortcode/src/Shortcode/ParsedShortcode.php b/vendor/thunderer/shortcode/src/Shortcode/ParsedShortcode.php index b2d2138..ba1ebe6 100644 --- a/vendor/thunderer/shortcode/src/Shortcode/ParsedShortcode.php +++ b/vendor/thunderer/shortcode/src/Shortcode/ParsedShortcode.php @@ -6,9 +6,15 @@ */ final class ParsedShortcode extends AbstractShortcode implements ParsedShortcodeInterface { + /** @var string */ private $text; + /** @var int */ private $offset; + /** + * @param string $text + * @param int $offset + */ public function __construct(ShortcodeInterface $shortcode, $text, $offset) { $this->name = $shortcode->getName(); @@ -27,11 +33,13 @@ public function withContent($content) return $self; } + /** @return string */ public function getText() { return $this->text; } + /** @return int */ public function getOffset() { return $this->offset; diff --git a/vendor/thunderer/shortcode/src/Shortcode/ProcessedShortcode.php b/vendor/thunderer/shortcode/src/Shortcode/ProcessedShortcode.php index 993b8f2..e6c212d 100644 --- a/vendor/thunderer/shortcode/src/Shortcode/ProcessedShortcode.php +++ b/vendor/thunderer/shortcode/src/Shortcode/ProcessedShortcode.php @@ -9,54 +9,66 @@ */ final class ProcessedShortcode extends AbstractShortcode implements ParsedShortcodeInterface { - /** @var ShortcodeInterface */ + /** @var ProcessedShortcode|null */ private $parent; + /** @var int */ private $position; + /** @var int */ private $namePosition; + /** @var string */ private $text; + /** @var string */ private $textContent; + /** @var int */ private $offset; + /** @var int */ private $baseOffset; + /** @var string */ private $shortcodeText; + /** @var int */ private $iterationNumber; + /** @var int */ private $recursionLevel; /** @var ProcessorInterface */ private $processor; - private function __construct() + private function __construct(ProcessorContext $context) { - } - - public static function createFromContext(ProcessorContext $context) - { - $self = new self(); - // basic properties - $self->name = $context->shortcode->getName(); - $self->parameters = $context->shortcode->getParameters(); - $self->content = $context->shortcode->getContent(); - $self->bbCode = $context->shortcode->getBbCode(); - $self->textContent = $context->textContent; + $this->name = $context->shortcode->getName(); + $this->parameters = $context->shortcode->getParameters(); + $this->content = $context->shortcode->getContent(); + $this->bbCode = $context->shortcode->getBbCode(); + $this->textContent = $context->textContent; // runtime context - $self->parent = $context->parent; - $self->position = $context->position; - $self->namePosition = $context->namePosition[$self->name]; - $self->text = $context->text; - $self->shortcodeText = $context->shortcodeText; + $this->parent = $context->parent; + $this->position = $context->position; + $this->namePosition = $context->namePosition[$this->name]; + $this->text = $context->text; + $this->shortcodeText = $context->shortcodeText; // processor state - $self->iterationNumber = $context->iterationNumber; - $self->recursionLevel = $context->recursionLevel; - $self->processor = $context->processor; + $this->iterationNumber = $context->iterationNumber; + $this->recursionLevel = $context->recursionLevel; + $this->processor = $context->processor; // text context - $self->offset = $context->offset; - $self->baseOffset = $context->baseOffset; + $this->offset = $context->offset; + $this->baseOffset = $context->baseOffset; + } - return $self; + /** @return self */ + public static function createFromContext(ProcessorContext $context) + { + return new self($context); } + /** + * @param string|null $content + * + * @return self + */ public function withContent($content) { $self = clone $this; @@ -65,6 +77,11 @@ public function withContent($content) return $self; } + /** + * @param string $name + * + * @return bool + */ public function hasAncestor($name) { $self = $this; @@ -78,56 +95,67 @@ public function hasAncestor($name) return false; } + /** @return ProcessedShortcode|null */ public function getParent() { return $this->parent; } + /** @return string */ public function getTextContent() { return $this->textContent; } + /** @return int */ public function getPosition() { return $this->position; } + /** @return int */ public function getNamePosition() { return $this->namePosition; } + /** @return string */ public function getText() { return $this->text; } + /** @return string */ public function getShortcodeText() { return $this->shortcodeText; } + /** @return int */ public function getOffset() { return $this->offset; } + /** @return int */ public function getBaseOffset() { return $this->baseOffset; } + /** @return int */ public function getIterationNumber() { return $this->iterationNumber; } + /** @return int */ public function getRecursionLevel() { return $this->recursionLevel; } + /** @return ProcessorInterface */ public function getProcessor() { return $this->processor; diff --git a/vendor/thunderer/shortcode/src/Shortcode/ReplacedShortcode.php b/vendor/thunderer/shortcode/src/Shortcode/ReplacedShortcode.php index 45e49c6..6fa89cb 100644 --- a/vendor/thunderer/shortcode/src/Shortcode/ReplacedShortcode.php +++ b/vendor/thunderer/shortcode/src/Shortcode/ReplacedShortcode.php @@ -6,10 +6,14 @@ */ final class ReplacedShortcode extends AbstractShortcode { + /** @var string */ private $replacement; + /** @var string */ private $text; + /** @var int */ private $offset; + /** @param string $replacement */ public function __construct(ParsedShortcodeInterface $shortcode, $replacement) { $this->name = $shortcode->getName(); @@ -22,16 +26,19 @@ public function __construct(ParsedShortcodeInterface $shortcode, $replacement) $this->replacement = $replacement; } + /** @return string */ public function getReplacement() { return $this->replacement; } + /** @return string */ public function getText() { return $this->text; } + /** @return int */ public function getOffset() { return $this->offset; diff --git a/vendor/thunderer/shortcode/src/Shortcode/Shortcode.php b/vendor/thunderer/shortcode/src/Shortcode/Shortcode.php index 99bcb2b..abda34c 100644 --- a/vendor/thunderer/shortcode/src/Shortcode/Shortcode.php +++ b/vendor/thunderer/shortcode/src/Shortcode/Shortcode.php @@ -6,12 +6,21 @@ */ final class Shortcode extends AbstractShortcode implements ShortcodeInterface { + /** + * @param string $name + * @param array $parameters + * @psalm-param array $parameters + * @param string|null $content + * @param string|null $bbCode + */ public function __construct($name, array $parameters, $content, $bbCode = null) { + /** @psalm-suppress RedundantConditionGivenDocblockType, DocblockTypeContradiction */ if(false === is_string($name) || '' === $name) { throw new \InvalidArgumentException('Shortcode name must be a non-empty string!'); } + /** @psalm-suppress MissingClosureParamType, MissingClosureReturnType */ $isStringOrNull = function($value) { return is_string($value) || null === $value; }; if(count(array_filter($parameters, $isStringOrNull)) !== count($parameters)) { throw new \InvalidArgumentException('Parameter values must be either string or empty (null)!'); diff --git a/vendor/thunderer/shortcode/src/Shortcode/ShortcodeInterface.php b/vendor/thunderer/shortcode/src/Shortcode/ShortcodeInterface.php index 0e832e2..377942a 100644 --- a/vendor/thunderer/shortcode/src/Shortcode/ShortcodeInterface.php +++ b/vendor/thunderer/shortcode/src/Shortcode/ShortcodeInterface.php @@ -26,6 +26,7 @@ public function getName(); * Returns associative array(name => value) of shortcode parameters * * @return array + * @psalm-return array */ public function getParameters(); @@ -53,7 +54,7 @@ public function getContent(); * Returns the so-called "BBCode" fragment when shortcode name is treated * like a parameter, eg.: [name="value" /] * - * @return string + * @return string|null */ public function getBbCode(); } diff --git a/vendor/thunderer/shortcode/src/ShortcodeFacade.php b/vendor/thunderer/shortcode/src/ShortcodeFacade.php index 75ee30a..32cf1ce 100644 --- a/vendor/thunderer/shortcode/src/ShortcodeFacade.php +++ b/vendor/thunderer/shortcode/src/ShortcodeFacade.php @@ -13,6 +13,7 @@ use Thunder\Shortcode\Serializer\TextSerializer; use Thunder\Shortcode\Serializer\XmlSerializer; use Thunder\Shortcode\Serializer\YamlSerializer; +use Thunder\Shortcode\Shortcode\ParsedShortcodeInterface; use Thunder\Shortcode\Shortcode\ShortcodeInterface; use Thunder\Shortcode\Syntax\CommonSyntax; use Thunder\Shortcode\Syntax\SyntaxInterface; @@ -58,11 +59,15 @@ public function __construct() $this->xmlSerializer = new XmlSerializer(); } - /** @deprecated use constructor and customize using exposed methods */ + /** + * @deprecated use constructor and customize using exposed methods + * @return self + */ public static function create(HandlerContainerInterface $handlers, SyntaxInterface $syntax) { $self = new self(); + /** @psalm-suppress PropertyTypeCoercion */ $self->handlers = $handlers; $self->syntax = $syntax; $self->rebuildProcessor(); @@ -70,22 +75,34 @@ public static function create(HandlerContainerInterface $handlers, SyntaxInterfa return $self; } + /** @return void */ private function rebuildProcessor() { $this->processor = new Processor($this->parser, $this->handlers); $this->processor = $this->processor->withEventContainer($this->events); } + /** + * @param string $text + * + * @return string + */ public function process($text) { return $this->processor->process($text); } + /** + * @param string $text + * + * @return ParsedShortcodeInterface[] + */ public function parse($text) { return $this->parser->parse($text); } + /** @return $this */ public function setParser(ParserInterface $parser) { $this->parser = $parser; @@ -94,6 +111,12 @@ public function setParser(ParserInterface $parser) return $this; } + /** + * @param string $name + * @psalm-param callable(ShortcodeInterface):string $handler + * + * @return $this + */ public function addHandler($name, $handler) { $this->handlers->add($name, $handler); @@ -101,6 +124,12 @@ public function addHandler($name, $handler) return $this; } + /** + * @param string $alias + * @param string $name + * + * @return $this + */ public function addHandlerAlias($alias, $name) { $this->handlers->addAlias($alias, $name); @@ -108,6 +137,12 @@ public function addHandlerAlias($alias, $name) return $this; } + /** + * @param string $name + * @param callable $handler + * + * @return $this + */ public function addEventHandler($name, $handler) { $this->events->addListener($name, $handler); @@ -117,6 +152,11 @@ public function addEventHandler($name, $handler) /* --- SERIALIZATION --------------------------------------------------- */ + /** + * @param string $format + * + * @return string + */ public function serialize(ShortcodeInterface $shortcode, $format) { switch($format) { @@ -128,6 +168,12 @@ public function serialize(ShortcodeInterface $shortcode, $format) } } + /** + * @param string $text + * @param string $format + * + * @return ShortcodeInterface + */ public function unserialize($text, $format) { switch($format) { @@ -139,12 +185,31 @@ public function unserialize($text, $format) } } - /** @deprecated use serialize($shortcode, $format) */ + /** + * @deprecated use serialize($shortcode, $format) + * @return string + */ public function serializeToText(ShortcodeInterface $s) { return $this->serialize($s, 'text'); } - /** @deprecated use serialize($shortcode, $format) */ + + /** + * @deprecated use serialize($shortcode, $format) + * @return string + */ public function serializeToJson(ShortcodeInterface $s) { return $this->serialize($s, 'json'); } - /** @deprecated use unserialize($shortcode, $format) */ + + /** + * @deprecated use serialize($shortcode, $format) + * @param string $text + * + * @return ShortcodeInterface + */ public function unserializeFromText($text) { return $this->unserialize($text, 'text'); } - /** @deprecated use unserialize($shortcode, $format) */ + + /** + * @deprecated use serialize($shortcode, $format) + * @param string $text + * + * @return ShortcodeInterface + */ public function unserializeFromJson($text) { return $this->unserialize($text, 'json'); } } diff --git a/vendor/thunderer/shortcode/src/Syntax/CommonSyntax.php b/vendor/thunderer/shortcode/src/Syntax/CommonSyntax.php index 901a6a1..f3bb64b 100644 --- a/vendor/thunderer/shortcode/src/Syntax/CommonSyntax.php +++ b/vendor/thunderer/shortcode/src/Syntax/CommonSyntax.php @@ -6,26 +6,31 @@ */ final class CommonSyntax implements SyntaxInterface { + /** @return string */ public function getOpeningTag() { return '['; } + /** @return string */ public function getClosingTag() { return ']'; } + /** @return string */ public function getClosingTagMarker() { return '/'; } + /** @return string */ public function getParameterValueSeparator() { return '='; } + /** @return string */ public function getParameterValueDelimiter() { return '"'; diff --git a/vendor/thunderer/shortcode/src/Syntax/Syntax.php b/vendor/thunderer/shortcode/src/Syntax/Syntax.php index 6695bd2..0b8b6cd 100644 --- a/vendor/thunderer/shortcode/src/Syntax/Syntax.php +++ b/vendor/thunderer/shortcode/src/Syntax/Syntax.php @@ -6,12 +6,24 @@ */ final class Syntax implements SyntaxInterface { + /** @var string|null */ private $openingTag; + /** @var string|null */ private $closingTag; + /** @var string|null */ private $closingTagMarker; + /** @var string|null */ private $parameterValueSeparator; + /** @var string|null */ private $parameterValueDelimiter; + /** + * @param string|null $openingTag + * @param string|null $closingTag + * @param string|null $closingTagMarker + * @param string|null $parameterValueSeparator + * @param string|null $parameterValueDelimiter + */ public function __construct( $openingTag = null, $closingTag = null, @@ -26,26 +38,31 @@ public function __construct( $this->parameterValueDelimiter = $parameterValueDelimiter; } + /** @return string */ public function getOpeningTag() { return $this->openingTag ?: '['; } + /** @return string */ public function getClosingTag() { return $this->closingTag ?: ']'; } + /** @return string */ public function getClosingTagMarker() { return $this->closingTagMarker ?: '/'; } + /** @return string */ public function getParameterValueSeparator() { return $this->parameterValueSeparator ?: '='; } + /** @return string */ public function getParameterValueDelimiter() { return $this->parameterValueDelimiter ?: '"'; diff --git a/vendor/thunderer/shortcode/src/Syntax/SyntaxBuilder.php b/vendor/thunderer/shortcode/src/Syntax/SyntaxBuilder.php index 4c13809..15437fb 100644 --- a/vendor/thunderer/shortcode/src/Syntax/SyntaxBuilder.php +++ b/vendor/thunderer/shortcode/src/Syntax/SyntaxBuilder.php @@ -6,16 +6,22 @@ */ final class SyntaxBuilder { + /** @var string|null */ private $openingTag; + /** @var string|null */ private $closingTag; + /** @var string|null */ private $closingTagMarker; + /** @var string|null */ private $parameterValueSeparator; + /** @var string|null */ private $parameterValueDelimiter; public function __construct() { } + /** @return Syntax */ public function getSyntax() { return new Syntax( @@ -27,6 +33,11 @@ public function getSyntax() ); } + /** + * @param string $tag + * + * @return $this + */ public function setOpeningTag($tag) { $this->openingTag = $tag; @@ -34,6 +45,11 @@ public function setOpeningTag($tag) return $this; } + /** + * @param string $tag + * + * @return $this + */ public function setClosingTag($tag) { $this->closingTag = $tag; @@ -41,6 +57,11 @@ public function setClosingTag($tag) return $this; } + /** + * @param string $marker + * + * @return $this + */ public function setClosingTagMarker($marker) { $this->closingTagMarker = $marker; @@ -48,6 +69,11 @@ public function setClosingTagMarker($marker) return $this; } + /** + * @param string $separator + * + * @return $this + */ public function setParameterValueSeparator($separator) { $this->parameterValueSeparator = $separator; @@ -55,6 +81,11 @@ public function setParameterValueSeparator($separator) return $this; } + /** + * @param string $delimiter + * + * @return $this + */ public function setParameterValueDelimiter($delimiter) { $this->parameterValueDelimiter = $delimiter; diff --git a/vendor/thunderer/shortcode/src/Syntax/SyntaxInterface.php b/vendor/thunderer/shortcode/src/Syntax/SyntaxInterface.php index 8600e35..3f352c6 100644 --- a/vendor/thunderer/shortcode/src/Syntax/SyntaxInterface.php +++ b/vendor/thunderer/shortcode/src/Syntax/SyntaxInterface.php @@ -6,13 +6,18 @@ */ interface SyntaxInterface { + /** @return string */ public function getOpeningTag(); + /** @return string */ public function getClosingTag(); + /** @return string */ public function getClosingTagMarker(); + /** @return string */ public function getParameterValueSeparator(); + /** @return string */ public function getParameterValueDelimiter(); } diff --git a/vendor/thunderer/shortcode/src/Utility/RegexBuilderUtility.php b/vendor/thunderer/shortcode/src/Utility/RegexBuilderUtility.php index dfc8307..847ff38 100644 --- a/vendor/thunderer/shortcode/src/Utility/RegexBuilderUtility.php +++ b/vendor/thunderer/shortcode/src/Utility/RegexBuilderUtility.php @@ -8,21 +8,25 @@ */ final class RegexBuilderUtility { + /** @return string */ public static function buildNameRegex() { return '[a-zA-Z0-9-_\\*]+'; } + /** @return string */ public static function buildShortcodeRegex(SyntaxInterface $syntax) { return '~('.self::createShortcodeRegexContent($syntax).')~us'; } + /** @return string */ public static function buildSingleShortcodeRegex(SyntaxInterface $syntax) { return '~(\A'.self::createShortcodeRegexContent($syntax).'\Z)~us'; } + /** @return string */ public static function buildParametersRegex(SyntaxInterface $syntax) { $equals = self::quote($syntax->getParameterValueSeparator()); @@ -39,6 +43,7 @@ public static function buildParametersRegex(SyntaxInterface $syntax) return '~(?:\s*(\w+(?:'.$complex.'|'.$simple.'|'.$empty.')))~us'; } + /** @return string */ private static function createShortcodeRegexContent(SyntaxInterface $syntax) { $open = self::quote($syntax->getOpeningTag()); @@ -78,6 +83,11 @@ private static function createShortcodeRegexContent(SyntaxInterface $syntax) return '(?:'.$common.'(?:'.$withContent.'|'.$justClosed.'|'.$selfClosed.'))'; } + /** + * @param string $text + * + * @return string + */ private static function quote($text) { return preg_replace('/(.)/us', '\\\\$0', $text); From 846cb323325cf0c0f4741e94c192555bcbabc554 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 10 May 2022 11:33:54 -0600 Subject: [PATCH 2/3] updated changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fa103d..fb48d56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v5.1.2 +## mm/dd/2022 + +1. [](#bugfix) + * Upgraded `thunderer/shortcode` to 0.7.5 to address a security issue + # v5.1.1 ## 01/11/2022 From eb7538ff686936abf27aa1666c501b6936f6bc00 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 10 May 2022 11:34:51 -0600 Subject: [PATCH 3/3] prepare for release --- CHANGELOG.md | 2 +- blueprints.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb48d56..7207df5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # v5.1.2 -## mm/dd/2022 +## 05/10/2022 1. [](#bugfix) * Upgraded `thunderer/shortcode` to 0.7.5 to address a security issue diff --git a/blueprints.yaml b/blueprints.yaml index 6e10b04..e823cb4 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -1,7 +1,7 @@ name: Shortcode Core slug: shortcode-core type: plugin -version: 5.1.1 +version: 5.1.2 description: "This plugin provides the core functionality for shortcode plugins" icon: code author: