diff --git a/.gitignore b/.gitignore index f5cd204f..c681ae63 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ vendor/ composer.lock tests/Fixtures/App/var !tests/Fixtures/App/var/.gitempty +build +.phpunit +.php_cs.cache diff --git a/.php_cs.dist b/.php_cs.dist new file mode 100644 index 00000000..5759af56 --- /dev/null +++ b/.php_cs.dist @@ -0,0 +1,64 @@ + true, + '@Symfony:risky' => true, + 'array_syntax' => [ + 'syntax' => 'short', + ], + 'combine_consecutive_issets' => true, + 'combine_consecutive_unsets' => true, + 'header_comment' => [ + 'header' => $header, + ], + 'no_extra_blank_lines' => true, + 'no_php4_constructor' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'ordered_class_elements' => true, + 'ordered_imports' => true, + 'phpdoc_order' => true, + '@PHP56Migration' => true, + '@PHP56Migration:risky' => true, + '@PHPUnit57Migration:risky' => true, + '@PHP70Migration' => true, + '@PHP70Migration:risky' => true, + '@PHPUnit60Migration:risky' => true, + '@PHP71Migration' => true, + '@PHP71Migration:risky' => true, + 'compact_nullable_typehint' => true, + 'void_return' => null, + 'strict_comparison' => true, + 'strict_param' => true, +]; + + +$finder = PhpCsFixer\Finder::create() + ->in(__DIR__) + ->exclude('Tests/Fixtures') + ->exclude('tests/Fixtures') + ->exclude('Resources/skeleton') + ->exclude('Resources/public/vendor') +; + +return PhpCsFixer\Config::create() + ->setFinder($finder) + ->setRiskyAllowed(true) + ->setRules($rules) + ->setUsingCache(true) +; diff --git a/.styleci.yml b/.styleci.yml index 2bdb04b1..c721eb61 100644 --- a/.styleci.yml +++ b/.styleci.yml @@ -7,7 +7,7 @@ ############################################################################ # This file is part of the Symfony CMF package. # # # -# (c) 2011-2017 Symfony CMF # +# (c) Symfony CMF # # # # For the full copyright and license information, please view the LICENSE # # file that was distributed with this source code. # diff --git a/.travis.yml b/.travis.yml index a42a6568..77a1266c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ ############################################################################ # This file is part of the Symfony CMF package. # # # -# (c) 2011-2017 Symfony CMF # +# (c) Symfony CMF # # # # For the full copyright and license information, please view the LICENSE # # file that was distributed with this source code. # @@ -17,7 +17,8 @@ language: php php: - 7.1 - + - 7.2 + - 7.3 sudo: false cache: @@ -26,26 +27,32 @@ cache: - $HOME/.composer/cache/files env: - matrix: SYMFONY_VERSION=4.0.* + matrix: SYMFONY_VERSION=4.2.* global: - SYMFONY_DEPRECATIONS_HELPER="/.*each.*/" - SYMFONY_PHPUNIT_DIR=.phpunit SYMFONY_PHPUNIT_REMOVE="symfony/yaml" - - KERNEL_CLASS=Symfony\Cmf\Bundle\BlockBundle\Tests\Fixtures\App\Kernel - - SYMFONY_PHPUNIT_VERSION=5.7 - - TEST_INSTALLATION=false + - SYMFONY_PHPUNIT_VERSION=7 + - PHPUNIT_VERSION=7 + - TARGET=test matrix: include: - - php: 7.2 - env: SYMFONY_VERSION=4.0.* + - env: TARGET=lint + - php: 7.3 + env: STABILITY="dev" SYMFONY_VERSION=4.3.* + - php: 7.3 + env: SYMFONY_VERSION=4.2.* - php: 7.1 - env: COMPOSER_FLAGS="--prefer-lowest" SYMFONY_VERSION=2.8.* SYMFONY_DEPRECATIONS_HELPER=weak - - php: 7.2 - env: SYMFONY_VERSION=3.3.* + env: COMPOSER_FLAGS="--prefer-lowest" SYMFONY_VERSION=3.4.* SYMFONY_DEPRECATIONS_HELPER="/.*each.*/" + - php: 7.2 - env: SYMFONY_VERSION=3.4.* + env: SYMFONY_VERSION=4.1.* + - env: TARGET=test_installation fast_finish: true allow_failures: + - php: 7.3 + env: STABILITY="dev" SYMFONY_VERSION=4.3.* + - env: TARGET=test_installation before_install: - phpenv config-rm xdebug.ini || true @@ -58,9 +65,12 @@ before_install: install: - phpenv config-add travis.php.ini - php -ini | grep memory_limit - - travis_wait composer update --prefer-dist $COMPOSER_FLAGS -script: - - if [ "${TEST_INSTALLATION}" == true ]; then make test_installation; else make test; fi + - if [ -x .travis/install_${TARGET}.sh ]; then .travis/install_${TARGET}.sh; fi; + +script: make $TARGET + +after_success: + - if [ -x .travis/after_success_${TARGET}.sh ]; then .travis/after_success_${TARGET}.sh; fi; notifications: irc: "irc.freenode.org#symfony-cmf" diff --git a/.travis/after_success_test.sh b/.travis/after_success_test.sh new file mode 100755 index 00000000..98374202 --- /dev/null +++ b/.travis/after_success_test.sh @@ -0,0 +1,5 @@ + +#!/usr/bin/env sh +set -ev + +coveralls -v diff --git a/.travis/install_lint.sh b/.travis/install_lint.sh new file mode 100755 index 00000000..864c751e --- /dev/null +++ b/.travis/install_lint.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env sh +set -ev + +mkdir --parents "${HOME}/bin" + +wget "http://cs.sensiolabs.org/download/php-cs-fixer-v2.phar" --output-document="${HOME}/bin/php-cs-fixer" +chmod u+x "${HOME}/bin/php-cs-fixer" + +composer global require sllh/composer-lint:@stable --prefer-dist --no-interaction + +gem install yaml-lint diff --git a/.travis/install_test.sh b/.travis/install_test.sh new file mode 100755 index 00000000..a0335009 --- /dev/null +++ b/.travis/install_test.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env sh +set -ev + +mkdir --parents "${HOME}/bin" + +wget "https://phar.phpunit.de/phpunit-${PHPUNIT_VERSION}.phar" --output-document="${HOME}/bin/phpunit" +chmod u+x "${HOME}/bin/phpunit" + +# Coveralls client install +wget https://github.com/satooshi/php-coveralls/releases/download/v1.0.1/coveralls.phar --output-document="${HOME}/bin/coveralls" +chmod u+x "${HOME}/bin/coveralls" + +# To be removed when these issues are resolved: +# https://github.com/composer/composer/issues/5355 +if [ "${COMPOSER_FLAGS}" = '--prefer-lowest' ]; then + composer update --prefer-dist --no-interaction --prefer-stable --quiet +fi + +composer update --prefer-dist --no-interaction --prefer-stable ${COMPOSER_FLAGS} diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c0a2373..9e0b5701 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,10 @@ Changelog ========= -3.0.0 (unreleased) ------------------- +2.2.0 (unreleased) +------------------ +* **2019-02-28**: Symfony 4.2 support without warnings 2.1.1 ----- @@ -20,7 +21,7 @@ Changelog Release 2.0.0 -2.0.0-RC2 +2.0.0-RC2Mo --------- * **2017-02-10**: [BC BREAK] Removed the `ImagineBlock` as the CmfMediaBundle diff --git a/Makefile b/Makefile index f81e5035..e76ce013 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ ############################################################################ # This file is part of the Symfony CMF package. # # # -# (c) 2011-2017 Symfony CMF # +# (c) Symfony CMF # # # # For the full copyright and license information, please view the LICENSE # # file that was distributed with this source code. # @@ -20,15 +20,63 @@ ifdef BRANCH VERSION=dev-${BRANCH} endif PACKAGE=symfony-cmf/block-bundle -export KERNEL_CLASS=Symfony\Cmf\Bundle\BlockBundle\Tests\Fixtures\App\Kernel +HAS_XDEBUG=$(shell php --modules|grep --quiet xdebug;echo $$?) + list: @echo 'test: will run all tests' @echo 'unit_tests: will run unit tests only' @echo 'functional_tests_phpcr: will run functional tests with PHPCR' - -include ${TESTING_SCRIPTS_DIR}/make/unit_tests.mk -include ${TESTING_SCRIPTS_DIR}/make/functional_tests_phpcr.mk + @echo 'test_installation: will run installation test'TEST_DEPENDENCIES := "" +EXTRA_INCLUDES:=$(wildcard ${TESTING_SCRIPTS_DIR}/make/unit_tests.mk) +ifneq ($(strip $(EXTRA_INCLUDES)),) + contents := $(shell echo including extra rules $(EXTRA_INCLUDES)) + include $(EXTRA_INCLUDES) + TEST_DEPENDENCIES := $(TEST_DEPENDENCIES)" unit_tests" + endif +EXTRA_INCLUDES:=$(wildcard ${TESTING_SCRIPTS_DIR}/make/functional_tests_phpcr.mk) +ifneq ($(strip $(EXTRA_INCLUDES)),) + contents := $(shell echo including extra rules $(EXTRA_INCLUDES)) + include $(EXTRA_INCLUDES) + TEST_DEPENDENCIES := $(TEST_DEPENDENCIES)" functional_tests_phpcr" + endif +EXTRA_INCLUDES:=$(wildcard ${TESTING_SCRIPTS_DIR}/make/test_installation.mk) +ifneq ($(strip $(EXTRA_INCLUDES)),) + contents := $(shell echo including extra rules $(EXTRA_INCLUDES)) + include $(EXTRA_INCLUDES) + endif .PHONY: test -test: unit_tests functional_tests_phpcr +test: build/xdebug-filter.php$ +ifneq ($(strip $(wildcard ${TESTING_SCRIPTS_DIR}/make/unit_tests.mk)),) + @make unit_tests +endif +ifneq ($(strip $(wildcard ${TESTING_SCRIPTS_DIR}/make/functional_tests_phpcr.mk)),) + @make functional_tests_phpcr +endif + +lint-php: + php-cs-fixer fix --ansi --verbose --diff --dry-run +.PHONY: lint-php + +lint: lint-composer lint-php +.PHONY: lint + +lint-composer: + composer validate +.PHONY: lint-composer + +cs-fix: cs-fix-php +.PHONY: cs-fix + +cs-fix-php: + php-cs-fixer fix --verbose +.PHONY: cs-fix-php + +build: + mkdir $@ + +build/xdebug-filter.php: phpunit.xml.dist build +ifeq ($(HAS_XDEBUG), 0) + phpunit --dump-xdebug-filter $@ +endif diff --git a/README.md b/README.md index a290b4ef..97c34bb6 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,11 @@ Branch | Travis | Coveralls | Scrutinizer | ------ | ------ | --------- | ----------- | -2.x | [![Build Status][travis_stable_badge]][travis_stable_link] | [![Coverage Status][coveralls_stable_badge]][coveralls_stable_link] | [![Scrutinizer Status][scrutinizer_stable_badge]][scrutinizer_stable_link] | -master | [![Build Status][travis_unstable_badge]][travis_unstable_link] | [![Coverage Status][coveralls_unstable_badge]][coveralls_unstable_link] | [![Scrutinizer Status][scrutinizer_unstable_badge]][scrutinizer_unstable_link] | +2.1 | [![Build Status][travis_stable_badge]][travis_stable_link] | [![Coverage Status][coveralls_stable_badge]][coveralls_stable_link] | [![Scrutinizer Status][scrutinizer_stable_badge]][scrutinizer_stable_link] | +dev-master | [![Build Status][travis_unstable_badge]][travis_unstable_link] | [![Coverage Status][coveralls_unstable_badge]][coveralls_unstable_link] | [![Scrutinizer Status][scrutinizer_unstable_badge]][scrutinizer_unstable_link] | -This package is part of the [Symfony Content Management Framework (CMF)](http://cmf.symfony.com/) and licensed +This package is part of the [Symfony Content Management Framework (CMF)](https://cmf.symfony.com/) and licensed under the [MIT License](LICENSE). The BlockBundle provides integration with @@ -26,24 +26,24 @@ provides a few commonly used standard blocks, including the ability to edit them ## Requirements -* PHP 7.1 / 7.2 -* Symfony 2.8 / 3.3 / 3.4 / 4.0 +* PHP 7.1 / 7.2 / 7.3 +* Symfony 3.4 / 4.1 / 4.2 * See also the `require` section of [composer.json](composer.json) ## Documentation For the install guide and reference, see: -* [symfony-cmf/block-bundle Documentation](http://symfony.com/doc/master/cmf/bundles/block/index.html) +* [symfony-cmf/block-bundle Documentation](https://symfony.com/doc/master/cmf/bundles/block/index.html) See also: -* [All Symfony CMF documentation](http://symfony.com/doc/master/cmf/index.html) - complete Symfony CMF reference -* [Symfony CMF Website](http://cmf.symfony.com/) - introduction, live demo, support and community links +* [All Symfony CMF documentation](https://symfony.com/doc/master/cmf/index.html) - complete Symfony CMF reference +* [Symfony CMF Website](https://cmf.symfony.com/) - introduction, live demo, support and community links ## Support -For general support and questions, please use [StackOverflow](http://stackoverflow.com/questions/tagged/symfony-cmf). +For general support and questions, please use [StackOverflow](https://stackoverflow.com/questions/tagged/symfony-cmf). ## Contributing @@ -52,7 +52,7 @@ Pull requests are welcome. Please see our guide. Unit and/or functional tests exist for this package. See the -[Testing documentation](http://symfony.com/doc/master/cmf/components/testing.html) +[Testing documentation](https://symfony.com/doc/master/cmf/components/testing.html) for a guide to running the tests. Thanks to @@ -62,17 +62,17 @@ Thanks to This package is available under the [MIT license](src/Resources/meta/LICENSE). -[travis_stable_badge]: https://travis-ci.org/symfony-cmf/block-bundle.svg?branch=2.x +[travis_stable_badge]: https://travis-ci.org/symfony-cmf/block-bundle.svg?branch=2.1 [travis_stable_link]: https://travis-ci.org/symfony-cmf/block-bundle -[travis_unstable_badge]: https://travis-ci.org/symfony-cmf/block-bundle.svg?branch=master +[travis_unstable_badge]: https://travis-ci.org/symfony-cmf/block-bundle.svg?branch=dev-master [travis_unstable_link]: https://travis-ci.org/symfony-cmf/block-bundle -[coveralls_stable_badge]: https://coveralls.io/repos/github/symfony-cmf/block-bundle/badge.svg?branch=2.x -[coveralls_stable_link]: https://coveralls.io/github/symfony-cmf/block-bundle?branch=2.x -[coveralls_unstable_badge]: https://coveralls.io/repos/github/symfony-cmf/block-bundle/badge.svg?branch=master -[coveralls_unstable_link]: https://coveralls.io/github/symfony-cmf/block-bundle?branch=master +[coveralls_stable_badge]: https://coveralls.io/repos/github/symfony-cmf/block-bundle/badge.svg?branch=2.1 +[coveralls_stable_link]: https://coveralls.io/github/symfony-cmf/block-bundle?branch=2.1 +[coveralls_unstable_badge]: https://coveralls.io/repos/github/symfony-cmf/block-bundle/badge.svg?branch=dev-master +[coveralls_unstable_link]: https://coveralls.io/github/symfony-cmf/block-bundle?branch=dev-master -[scrutinizer_stable_badge]: https://scrutinizer-ci.com/g/symfony-cmf/block-bundle/badges/quality-score.png?b=2.x -[scrutinizer_stable_link]: https://scrutinizer-ci.com/g/symfony-cmf/block-bundle/?branch=2.x -[scrutinizer_unstable_badge]: https://scrutinizer-ci.com/g/symfony-cmf/block-bundle/badges/quality-score.png?b=master -[scrutinizer_unstable_link]: https://scrutinizer-ci.com/g/symfony-cmf/block-bundle/?branch=master +[scrutinizer_stable_badge]: https://scrutinizer-ci.com/g/symfony-cmf/block-bundle/badges/quality-score.png?b=2.1 +[scrutinizer_stable_link]: https://scrutinizer-ci.com/g/symfony-cmf/block-bundle/?branch=2.1 +[scrutinizer_unstable_badge]: https://scrutinizer-ci.com/g/symfony-cmf/block-bundle/badges/quality-score.png?b=dev-master +[scrutinizer_unstable_link]: https://scrutinizer-ci.com/g/symfony-cmf/block-bundle/?branch=dev-master diff --git a/composer.json b/composer.json index 9bfb501e..620284ed 100644 --- a/composer.json +++ b/composer.json @@ -17,23 +17,24 @@ ], "require": { "php": "^7.1", - "symfony/framework-bundle": "^2.8 || ^3.3 || ^4.0", + "symfony/framework-bundle": "^3.4 || ^4.1", "doctrine/phpcr-bundle": "^1.3 || ^2.0", "doctrine/phpcr-odm": "^1.4.2 || ^2.0", - "sonata-project/block-bundle": "^3.11", - "symfony-cmf/core-bundle": "^2.0" + "sonata-project/block-bundle": "^3.15", + "symfony-cmf/core-bundle": "^2.0", + "twig/twig": "^1.14.2" }, "require-dev": { "symfony-cmf/testing": "^2.1.8", "symfony-cmf/menu-bundle": "^2.1", - "symfony/phpunit-bridge": "^3.3 || ^4.0", + "symfony/phpunit-bridge": "^4.2.2", "sonata-project/cache-bundle": "^2.4", "sonata-project/core-bundle": "^3.0", - "twig/twig": "^1.14.2 || ^2.0", - "symfony/security-bundle": "^2.8 || ^3.3 || ^4.0", - "symfony/twig-bundle": "^2.8 || ^3.3 || ^4.0", - "symfony/asset": "^2.8 || ^3.3 || ^4.0", - "symfony/templating": "^2.8 || ^3.3 || ^4.0" + "symfony/security-bundle": "^3.4 || ^4.1", + "symfony/twig-bundle": "^3.4 || ^4.1", + "symfony/asset": "^3.4 || ^4.1", + "symfony/templating": "^3.4 || ^4.1", + "symfony/yaml": "^3.4 || ^4.1" }, "suggest": { "sonata-project/cache-bundle": "To add caching support for block loading", diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 9e2fa8ea..d20f5260 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,26 +1,36 @@ + - - + + + + + ./tests/Unit - + - ./tests/WebTest ./tests/Functional + ./tests/Functional/Doctrine/Orm - + + + + + + src/ + + Resources/ + + + + + - - - src/ - - Resources/ - - - + + diff --git a/src/Block/ActionBlockService.php b/src/Block/ActionBlockService.php index 4d752503..9ba37838 100644 --- a/src/Block/ActionBlockService.php +++ b/src/Block/ActionBlockService.php @@ -1,9 +1,11 @@ getNotFoundBlock($configuration['name'], sprintf( "Document at '%s' is no Sonata\\BlockBundle\\Model\\BlockInterface but %s", $configuration['name'], - null === $block ? 'not existing' : get_class($block) + null === $block ? 'not existing' : \get_class($block) )); } @@ -140,7 +142,7 @@ public function load($configuration) */ public function support($configuration) { - if (!is_array($configuration)) { + if (!\is_array($configuration)) { return false; } @@ -151,6 +153,22 @@ public function support($configuration) return true; } + /** + * @return string|null service id of the empty block service, null if not set + */ + public function getEmptyBlockType() + { + return $this->emptyBlockType; + } + + /** + * @param string $type service id of the empty block service + */ + public function setEmptyBlockType($type = null) + { + $this->emptyBlockType = $type; + } + /** * Finds one block by the given name (PHPCR path). * @@ -197,8 +215,8 @@ protected function findByName($name) */ protected function isAbsolutePath($path) { - return is_string($path) - && strlen($path) > 0 + return \is_string($path) + && \strlen($path) > 0 && '/' === $path[0] ; } @@ -225,8 +243,16 @@ protected function determineAbsolutePath($name) ->getDocumentId($currentPage).'/'.$name ; } + } - return; + /** + * Get the object manager from the registry, based on the current managerName. + * + * @return \Doctrine\Common\Persistence\ObjectManager + */ + protected function getObjectManager() + { + return $this->managerRegistry->getManager($this->managerName); } /** @@ -238,9 +264,9 @@ protected function determineAbsolutePath($name) * @param string $name The block name that was not found or invalid * @param string $message The exception message if an exception should be raised * - * @return EmptyBlock - * * @throws BlockNotFoundException if there is no type defined for the empty block + * + * @return EmptyBlock */ private function getNotFoundBlock($name, $message = null) { @@ -259,30 +285,4 @@ private function getNotFoundBlock($name, $message = null) return $block; } - - /** - * @return string|null service id of the empty block service, null if not set - */ - public function getEmptyBlockType() - { - return $this->emptyBlockType; - } - - /** - * @param string $type service id of the empty block service - */ - public function setEmptyBlockType($type = null) - { - $this->emptyBlockType = $type; - } - - /** - * Get the object manager from the registry, based on the current managerName. - * - * @return \Doctrine\Common\Persistence\ObjectManager - */ - protected function getObjectManager() - { - return $this->managerRegistry->getManager($this->managerName); - } } diff --git a/src/Block/ReferenceBlockService.php b/src/Block/ReferenceBlockService.php index 01c50a29..cdf04272 100644 --- a/src/Block/ReferenceBlockService.php +++ b/src/Block/ReferenceBlockService.php @@ -1,9 +1,11 @@ validateKeys($keys); + + return new CacheElement($keys, $data, $ttl, $contextualKeys); + } + + /** + * @param \Symfony\Component\HttpFoundation\Request $request * - * @param array $keys + * @return \Symfony\Component\HttpFoundation\Response */ - private function validateKeys(array $keys) + public function cacheAction(Request $request) { - foreach (['block_id', 'updated_at'] as $key) { - if (!isset($keys[$key])) { - throw new \RuntimeException(sprintf('Please define a `%s` key', $key)); + $block = $this->blockLoader->load(['name' => $request->get('block_id')]); + + if (!$block) { + return new Response('', 404); + } + + $settings = $request->get(BlockContextManagerInterface::CACHE_KEY, []); + + if (!\is_array($settings)) { + throw new \RuntimeException(sprintf( + 'Query string parameter `%s` is not an array', + BlockContextManagerInterface::CACHE_KEY + )); + } + + $response = $this->blockRenderer->render( + $this->blockContextManager->get($block, $settings) + ); + $response->setPrivate(); // always set to private + + if ($this->sync) { + return $response; + } + + $response->setContent(sprintf(<<<'JS' + (function () { + var block = document.getElementById('block%s'), + div = document.createElement("div"), + parentNode = block.parentNode, + node, + replace = true; + + div.innerHTML = %s; + + for (var node in div.childNodes) { + if (div.childNodes[node] && div.childNodes[node].nodeType == 1) { + if (replace) { + parentNode.replaceChild(div.childNodes[node], block); + replace = false; + } else { + parentNode.appendChild(div.childNodes[node]); + } } } + })(); +JS +, $this->dashify($block->getId()), json_encode($response->getContent()))); + + $response->headers->set('Content-Type', 'application/javascript'); + + return $response; + } + + /** + * {@inheritdoc} + */ + public function isContextual() + { + return false; } /** @@ -183,90 +249,26 @@ protected function getAsync(array $keys) } /** - * {@inheritdoc} + * @param string $src + * + * @return mixed */ - public function set(array $keys, $data, $ttl = 84600, array $contextualKeys = []) + protected function dashify($src) { - $this->validateKeys($keys); - - return new CacheElement($keys, $data, $ttl, $contextualKeys); + return preg_replace('/[\/\.]/', '-', $src); } /** - * @param \Symfony\Component\HttpFoundation\Request $request + * @param array $keys * - * @return \Symfony\Component\HttpFoundation\Response + * @throws \RuntimeException */ - public function cacheAction(Request $request) + private function validateKeys(array $keys) { - $block = $this->blockLoader->load(['name' => $request->get('block_id')]); - - if (!$block) { - return new Response('', 404); - } - - $settings = $request->get(BlockContextManagerInterface::CACHE_KEY, []); - - if (!is_array($settings)) { - throw new \RuntimeException(sprintf( - 'Query string parameter `%s` is not an array', - BlockContextManagerInterface::CACHE_KEY - )); - } - - $response = $this->blockRenderer->render( - $this->blockContextManager->get($block, $settings) - ); - $response->setPrivate(); // always set to private - - if ($this->sync) { - return $response; - } - - $response->setContent(sprintf(<<<'JS' - (function () { - var block = document.getElementById('block%s'), - div = document.createElement("div"), - parentNode = block.parentNode, - node, - replace = true; - - div.innerHTML = %s; - - for (var node in div.childNodes) { - if (div.childNodes[node] && div.childNodes[node].nodeType == 1) { - if (replace) { - parentNode.replaceChild(div.childNodes[node], block); - replace = false; - } else { - parentNode.appendChild(div.childNodes[node]); - } + foreach (['block_id', 'updated_at'] as $key) { + if (!isset($keys[$key])) { + throw new \RuntimeException(sprintf('Please define a `%s` key', $key)); } } - })(); -JS -, $this->dashify($block->getId()), json_encode($response->getContent()))); - - $response->headers->set('Content-Type', 'application/javascript'); - - return $response; - } - - /** - * {@inheritdoc} - */ - public function isContextual() - { - return false; - } - - /** - * @param string $src - * - * @return mixed - */ - protected function dashify($src) - { - return preg_replace('/[\/\.]/', '-', $src); } } diff --git a/src/Cache/BlockSsiCache.php b/src/Cache/BlockSsiCache.php index 4fc91af5..837abf75 100644 --- a/src/Cache/BlockSsiCache.php +++ b/src/Cache/BlockSsiCache.php @@ -1,9 +1,11 @@ blockContextManager = $blockContextManager; } - /** - * @throws \RuntimeException - * - * @param array $keys - */ - private function validateKeys(array $keys) - { - foreach (['block_id', 'updated_at'] as $key) { - if (!isset($keys[$key])) { - throw new \RuntimeException(sprintf('Please define a `%s` key', $key)); - } - } - } - /** * {@inheritdoc} */ @@ -92,20 +80,6 @@ public function set(array $keys, $data, $ttl = 84600, array $contextualKeys = [] return new CacheElement($keys, $data, $ttl, $contextualKeys); } - /** - * @param array $keys - * - * @return string - */ - protected function computeHash(array $keys) - { - // values are casted into string for non numeric id - return hash('sha256', $this->token.serialize([ - 'block_id' => (string) $keys['block_id'], - 'updated_at' => (string) $keys['updated_at'], - ])); - } - /** * @param Request $request * @@ -130,7 +104,7 @@ public function cacheAction(Request $request) $settings = $request->get(BlockContextManagerInterface::CACHE_KEY, []); - if (!is_array($settings)) { + if (!\is_array($settings)) { throw new \RuntimeException(sprintf( 'Query string parameter `%s` is not an array', BlockContextManagerInterface::CACHE_KEY @@ -141,4 +115,32 @@ public function cacheAction(Request $request) $this->blockContextManager->get($block, $settings) ); } + + /** + * @param array $keys + * + * @return string + */ + protected function computeHash(array $keys) + { + // values are casted into string for non numeric id + return hash('sha256', $this->token.serialize([ + 'block_id' => (string) $keys['block_id'], + 'updated_at' => (string) $keys['updated_at'], + ])); + } + + /** + * @param array $keys + * + * @throws \RuntimeException + */ + private function validateKeys(array $keys) + { + foreach (['block_id', 'updated_at'] as $key) { + if (!isset($keys[$key])) { + throw new \RuntimeException(sprintf('Please define a `%s` key', $key)); + } + } + } } diff --git a/src/Cache/BlockVarnishCache.php b/src/Cache/BlockVarnishCache.php index 93a36735..c94e000d 100644 --- a/src/Cache/BlockVarnishCache.php +++ b/src/Cache/BlockVarnishCache.php @@ -1,9 +1,11 @@ fragmentHandler = $fragmentHandler; } - /** - * @throws \RuntimeException - * - * @param array $keys - */ - private function validateKeys(array $keys) - { - foreach (['block_id', 'updated_at'] as $key) { - if (!isset($keys[$key])) { - throw new \RuntimeException(sprintf('Please define a `%s` key', $key)); - } - } - } - /** * {@inheritdoc} */ @@ -119,20 +107,6 @@ public function set(array $keys, $data, $ttl = 84600, array $contextualKeys = [] return new CacheElement($keys, $data, $ttl, $contextualKeys); } - /** - * @param array $keys - * - * @return string - */ - protected function computeHash(array $keys) - { - // values are casted into string for non numeric id - return hash('sha256', $this->token.serialize([ - 'block_id' => (string) $keys['block_id'], - 'updated_at' => (string) $keys['updated_at'], - ])); - } - /** * @param Request $request * @@ -157,7 +131,7 @@ public function cacheAction(Request $request) $settings = $request->get(BlockContextManagerInterface::CACHE_KEY, []); - if (!is_array($settings)) { + if (!\is_array($settings)) { throw new \RuntimeException(sprintf( 'Query string parameter `%s` is not an array', BlockContextManagerInterface::CACHE_KEY @@ -168,4 +142,32 @@ public function cacheAction(Request $request) $this->blockContextManager->get($block, $settings) ); } + + /** + * @param array $keys + * + * @return string + */ + protected function computeHash(array $keys) + { + // values are casted into string for non numeric id + return hash('sha256', $this->token.serialize([ + 'block_id' => (string) $keys['block_id'], + 'updated_at' => (string) $keys['updated_at'], + ])); + } + + /** + * @param array $keys + * + * @throws \RuntimeException + */ + private function validateKeys(array $keys) + { + foreach (['block_id', 'updated_at'] as $key) { + if (!isset($keys[$key])) { + throw new \RuntimeException(sprintf('Please define a `%s` key', $key)); + } + } + } } diff --git a/src/CmfBlockBundle.php b/src/CmfBlockBundle.php index e814e095..74a54393 100644 --- a/src/CmfBlockBundle.php +++ b/src/CmfBlockBundle.php @@ -1,9 +1,11 @@ get('eko_feed.feed.reader'); $items = $reader->load($settings['url'])->populate($settings['itemClass']); - } catch (RuntimeException $e) { + } catch (\RuntimeException $e) { // feed import failed $this->get('logger')->debug(sprintf( 'RssBlock with id "%s" could not import feed from "%s", error: %s', @@ -75,6 +76,6 @@ protected function getItems(BlockContextInterface $blockContext) $items = []; } - return array_slice($items, 0, $settings['maxItems']); + return \array_slice($items, 0, $settings['maxItems']); } } diff --git a/src/DependencyInjection/CmfBlockExtension.php b/src/DependencyInjection/CmfBlockExtension.php index a2b39d09..806f52ad 100644 --- a/src/DependencyInjection/CmfBlockExtension.php +++ b/src/DependencyInjection/CmfBlockExtension.php @@ -1,9 +1,11 @@ loadSonataCache($config, $loader, $container); } + /** + * Returns the base path for the XSD files. + * + * @return string The XSD base path + */ + public function getXsdValidationBasePath() + { + return __DIR__.'/../Resources/config/schema'; + } + + public function getNamespace() + { + return 'http://cmf.symfony.com/schema/dic/block'; + } + private function loadPhpcr(array $config, XmlFileLoader $loader, ContainerBuilder $container) { $container->setParameter($this->getAlias().'.backend_type_phpcr', true); @@ -132,19 +149,4 @@ private function loadSonataCache(array $config, XmlFileLoader $loader, Container $container->removeDefinition('cmf.block.cache.ssi'); } } - - /** - * Returns the base path for the XSD files. - * - * @return string The XSD base path - */ - public function getXsdValidationBasePath() - { - return __DIR__.'/../Resources/config/schema'; - } - - public function getNamespace() - { - return 'http://cmf.symfony.com/schema/dic/block'; - } } diff --git a/src/DependencyInjection/Compiler/ValidationPass.php b/src/DependencyInjection/Compiler/ValidationPass.php index 71a359de..ee9aae8c 100644 --- a/src/DependencyInjection/Compiler/ValidationPass.php +++ b/src/DependencyInjection/Compiler/ValidationPass.php @@ -1,9 +1,11 @@ root('cmf_block'); + $treeBuilder = new TreeBuilder('cmf_block'); + // Keep compatibility with symfony/config < 4.2 + if (!method_exists($treeBuilder, 'getRootNode')) { + $rootNode = $treeBuilder->root('cmf_block'); + } else { + $rootNode = $treeBuilder->getRootNode(); + } $rootNode ->children() @@ -67,7 +74,7 @@ public function getConfigTreeBuilder() ->arrayNode('varnish') ->fixXmlConfig('server') ->children() - ->scalarNode('token')->defaultValue(hash('sha256', uniqid(mt_rand(), true)))->end() + ->scalarNode('token')->defaultValue(hash('sha256', uniqid((string) mt_rand(), true)))->end() ->scalarNode('version')->defaultValue(2)->end() ->arrayNode('servers') ->prototype('scalar')->end() @@ -76,7 +83,7 @@ public function getConfigTreeBuilder() ->end() ->arrayNode('ssi') ->children() - ->scalarNode('token')->defaultValue(hash('sha256', uniqid(mt_rand(), true)))->end() + ->scalarNode('token')->defaultValue(hash('sha256', uniqid((string) mt_rand(), true)))->end() ->end() ->end() ->end() diff --git a/src/Doctrine/Phpcr/AbstractBlock.php b/src/Doctrine/Phpcr/AbstractBlock.php index c108c17a..fdc19086 100644 --- a/src/Doctrine/Phpcr/AbstractBlock.php +++ b/src/Doctrine/Phpcr/AbstractBlock.php @@ -1,9 +1,11 @@ getSettings() as $value) { - if (is_array($value)) { + if (\is_array($value)) { $context->addViolation('settings', 'A multidimensional array is not allowed, only use key-value pairs.'); } } diff --git a/src/Doctrine/Phpcr/ActionBlock.php b/src/Doctrine/Phpcr/ActionBlock.php index 9687d8fb..73ddaf5c 100644 --- a/src/Doctrine/Phpcr/ActionBlock.php +++ b/src/Doctrine/Phpcr/ActionBlock.php @@ -1,9 +1,11 @@ children) > 0; + return \count($this->children) > 0; } } diff --git a/src/Doctrine/Phpcr/MenuBlock.php b/src/Doctrine/Phpcr/MenuBlock.php index b24d55d6..d65e7e93 100644 --- a/src/Doctrine/Phpcr/MenuBlock.php +++ b/src/Doctrine/Phpcr/MenuBlock.php @@ -1,9 +1,11 @@ name; } /** @@ -155,7 +157,7 @@ public function getPosition() { $siblings = $this->getParentObject()->getChildren(); - return array_search($siblings->indexOf($this), $siblings->getKeys()); + return array_search($siblings->indexOf($this), $siblings->getKeys(), true); } /** @@ -330,8 +332,6 @@ public function getParent() if (($parent = $this->getParentObject()) instanceof BlockInterface) { return $parent; } - - return; } /** @@ -364,16 +364,6 @@ public function getTtl() return $this->ttl; } - /** - * toString ... - * - * @return string - */ - public function __toString() - { - return (string) $this->name; - } - /** * {@inheritdoc} */ @@ -453,4 +443,14 @@ public function setLocale($locale) return $this; } + + /** + * @param string $src + * + * @return string + */ + protected function dashify($src) + { + return preg_replace('/[\/\.]/', '-', $src); + } } diff --git a/src/Model/FeedItem.php b/src/Model/FeedItem.php index d1c5fbf4..93165b50 100644 --- a/src/Model/FeedItem.php +++ b/src/Model/FeedItem.php @@ -1,9 +1,11 @@ segmentize($text); foreach ($segments as &$segment) { - if (!is_array($segment)) { + if (!\is_array($segment)) { continue; } diff --git a/src/Twig/Extension/CmfBlockExtension.php b/src/Twig/Extension/CmfBlockExtension.php index 6ed634cd..731644c5 100644 --- a/src/Twig/Extension/CmfBlockExtension.php +++ b/src/Twig/Extension/CmfBlockExtension.php @@ -1,9 +1,11 @@ registryMock, $this->pwcMock, $this->requestStackMock, null, 'emptyblocktype'); - $blockLoader->setManagerName('themanager'); - - return $blockLoader; - } - public function testSupport() { $blockLoader = $this->getSimpleBlockLoaderInstance(); @@ -269,6 +264,14 @@ public function testLoadWithAlternativeDocumentManager() $this->assertInstanceOf('Sonata\BlockBundle\Model\BlockInterface', $foundBlock); $this->assertEquals('alt-block', $foundBlock->getName()); } + + private function getSimpleBlockLoaderInstance() + { + $blockLoader = new PhpcrBlockLoader($this->registryMock, $this->pwcMock, $this->requestStackMock, null, 'emptyblocktype'); + $blockLoader->setManagerName('themanager'); + + return $blockLoader; + } } class MockContent diff --git a/tests/Functional/Block/ReferenceBlockServiceTest.php b/tests/Functional/Block/ReferenceBlockServiceTest.php index a5bb525a..450889cc 100644 --- a/tests/Functional/Block/ReferenceBlockServiceTest.php +++ b/tests/Functional/Block/ReferenceBlockServiceTest.php @@ -1,9 +1,11 @@ expectException(\RuntimeException::class); + $router = $this->createMock(RouterInterface::class); $blockRenderer = $this->createMock(BlockRendererInterface::class); diff --git a/tests/Unit/Cache/BlockSsiCacheTest.php b/tests/Unit/Cache/BlockSsiCacheTest.php index ca3d60e2..023a9864 100644 --- a/tests/Unit/Cache/BlockSsiCacheTest.php +++ b/tests/Unit/Cache/BlockSsiCacheTest.php @@ -1,9 +1,11 @@ expectException(\RuntimeException::class); + $router = $this->createMock(RouterInterface::class); $blockRenderer = $this->createMock(BlockRendererInterface::class); @@ -82,11 +86,10 @@ public function testInitCache() $this->assertEquals('', $cacheElement->getData()->getContent()); } - /** - * @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException - */ public function testAccessDenied() { + $this->expectException(\Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException::class); + $token = 'My Token'; $keys = [ 'block_id' => '/cms/content/home/additionalInfoBlock', @@ -108,11 +111,10 @@ public function testAccessDenied() $cache->cacheAction($request); } - /** - * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException - */ public function testBlockNotFound() { + $this->expectException(\Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class); + $token = 'My Token'; $keys = [ 'block_id' => '/not/found', diff --git a/tests/Unit/Cache/BlockVarnishCacheTest.php b/tests/Unit/Cache/BlockVarnishCacheTest.php index 09cc16bb..1527bdbb 100644 --- a/tests/Unit/Cache/BlockVarnishCacheTest.php +++ b/tests/Unit/Cache/BlockVarnishCacheTest.php @@ -1,9 +1,11 @@ expectException(\RuntimeException::class); + $router = $this->createMock(RouterInterface::class); $blockRenderer = $this->createMock(BlockRendererInterface::class); @@ -101,11 +105,10 @@ public function testInitCache() $this->assertEquals($content, $cacheElement->getData()->getContent()); } - /** - * @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException - */ public function testAccessDenied() { + $this->expectException(\Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException::class); + $token = 'My Token'; $keys = [ 'block_id' => '/cms/content/home/additionalInfoBlock', @@ -127,11 +130,10 @@ public function testAccessDenied() $cache->cacheAction($request); } - /** - * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException - */ public function testBlockNotFound() { + $this->expectException(\Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class); + $token = 'My Token'; $keys = [ 'block_id' => '/not/found', diff --git a/tests/Unit/DependencyInjection/XmlSchemaTest.php b/tests/Unit/DependencyInjection/XmlSchemaTest.php index c28c7b19..548d1814 100644 --- a/tests/Unit/DependencyInjection/XmlSchemaTest.php +++ b/tests/Unit/DependencyInjection/XmlSchemaTest.php @@ -1,9 +1,11 @@