mscherer 6 years ago
parent
commit
2122674f8b
61 changed files with 308 additions and 446 deletions
  1. 1 4
      .travis.yml
  2. 2 3
      composer.json
  3. 2 31
      docs/Install.md
  4. 5 2
      docs/Upgrade.md
  5. 54 40
      src/Controller/Component/CommonComponent.php
  6. 18 18
      src/Controller/Component/MobileComponent.php
  7. 3 3
      src/Controller/Component/RefererRedirectComponent.php
  8. 9 9
      src/Controller/Component/UrlComponent.php
  9. 0 43
      src/Database/Type/ArrayType.php
  10. 38 3
      src/Error/ErrorHandler.php
  11. 0 64
      src/Error/Middleware/ErrorHandlerMiddleware.php
  12. 3 3
      src/Form/ContactForm.php
  13. 7 2
      src/Mailer/Message.php
  14. 3 3
      src/Model/Behavior/AfterSaveBehavior.php
  15. 9 9
      src/Model/Behavior/BitmaskedBehavior.php
  16. 3 3
      src/Model/Behavior/ConfirmableBehavior.php
  17. 8 8
      src/Model/Behavior/JsonableBehavior.php
  18. 7 7
      src/Model/Behavior/PasswordableBehavior.php
  19. 7 7
      src/Model/Behavior/SluggedBehavior.php
  20. 6 5
      src/Model/Behavior/StringBehavior.php
  21. 7 7
      src/Model/Behavior/ToggleBehavior.php
  22. 5 5
      src/Model/Behavior/TypographicBehavior.php
  23. 5 29
      src/Model/Table/Table.php
  24. 1 1
      src/Model/Table/TokensTable.php
  25. 2 2
      src/Shell/InflectShell.php
  26. 3 7
      src/Utility/Number.php
  27. 7 1
      src/Utility/Utility.php
  28. 0 10
      src/View/Helper/QrCodeHelper.php
  29. 1 1
      src/View/Helper/TimeHelper.php
  30. 6 3
      src/View/Helper/TimelineHelper.php
  31. 3 3
      src/View/Helper/UrlHelper.php
  32. 1 0
      tests/Fixture/JsonableCommentsFixture.php
  33. 1 1
      tests/TestCase/Auth/MultiColumnAuthenticateTest.php
  34. 1 1
      tests/TestCase/Controller/Component/MobileComponentTest.php
  35. 1 1
      tests/TestCase/Controller/ControllerTest.php
  36. 1 1
      tests/TestCase/Controller/ShuntRequestControllerTest.php
  37. 0 60
      tests/TestCase/Error/Middleware/ErrorHandlerMiddlewareTest.php
  38. 1 1
      tests/TestCase/Form/ContactFormTest.php
  39. 1 1
      tests/TestCase/Model/Behavior/AfterSaveBehaviorTest.php
  40. 1 1
      tests/TestCase/Model/Behavior/BitmaskedBehaviorTest.php
  41. 1 1
      tests/TestCase/Model/Behavior/ConfirmableBehaviorTest.php
  42. 36 5
      tests/TestCase/Model/Behavior/JsonableBehaviorTest.php
  43. 1 1
      tests/TestCase/Model/Behavior/NeighborBehaviorTest.php
  44. 6 1
      tests/TestCase/Model/Behavior/PasswordableBehaviorTest.php
  45. 1 1
      tests/TestCase/Model/Behavior/ResetBehaviorTest.php
  46. 1 1
      tests/TestCase/Model/Behavior/SluggedBehaviorTest.php
  47. 1 1
      tests/TestCase/Model/Behavior/StringBehaviorTest.php
  48. 1 1
      tests/TestCase/Model/Behavior/ToggleBehaviorTest.php
  49. 1 1
      tests/TestCase/Model/Behavior/TypeMapBehaviorTest.php
  50. 1 1
      tests/TestCase/Model/Behavior/TypographicBehaviorTest.php
  51. 1 1
      tests/TestCase/Model/Entity/EntityTest.php
  52. 1 1
      tests/TestCase/Model/Table/TableTest.php
  53. 1 1
      tests/TestCase/Model/Table/TokensTableTest.php
  54. 3 3
      tests/TestCase/Utility/NumberTest.php
  55. 1 1
      tests/TestCase/View/Helper/FormatHelperTest.php
  56. 1 5
      tests/TestCase/View/Helper/NumberHelperTest.php
  57. 1 1
      tests/TestCase/View/Helper/TreeHelperTest.php
  58. 5 5
      tests/test_app/Controller/Component/AppleComponent.php
  59. 4 4
      tests/test_app/Controller/Component/BananaComponent.php
  60. 6 6
      tests/test_app/Controller/Component/TestComponent.php
  61. 1 1
      tests/test_app/Model/Table/ToolsUsersTable.php

+ 1 - 4
.travis.yml

@@ -41,7 +41,7 @@ before_script:
   - if [[ $PREFER_LOWEST == 1 ]]; then composer update --prefer-lowest --prefer-stable --prefer-dist --no-interaction ; fi
   - if [[ $PREFER_LOWEST == 1 ]]; then composer require --dev dereuromark/composer-prefer-lowest; fi
 
-  - if [[ $CHECKS != 1 ]]; then composer require --dev phpunit/phpunit:"^8.0"; fi
+  - if [[ $CHECKS != 1 ]]; then composer require --dev phpunit/phpunit:"^8.4"; fi
 
   - if [[ $DB == 'mysql' ]]; then mysql -e 'CREATE DATABASE cakephp_test;'; fi
   - if [[ $DB == 'pgsql' ]]; then psql -c 'CREATE DATABASE cakephp_test;' -U postgres; fi
@@ -61,6 +61,3 @@ after_success:
 cache:
   directories:
     - $HOME/.composer/cache
-
-notifications:
-  email: false

+ 2 - 3
composer.json

@@ -18,7 +18,7 @@
 		"dereuromark/cakephp-shim": "^2.0.0"
 	},
 	"require-dev": {
-		"dereuromark/cakephp-shim": "dev-cake4",
+		"dereuromark/cakephp-shim": "dev-cake4 as 2.0.0",
 		"cakephp/chronos": "^2.0",
 		"mobiledetect/mobiledetectlib": "^2.8",
 		"fig-r/psr2r-sniffer": "dev-master",
@@ -47,7 +47,7 @@
 	},
 	"scripts": {
 		"phpstan": "phpstan analyse -c tests/phpstan.neon -l 3 src/",
-		"phpstan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan-shim:^0.11.1 && mv composer.backup composer.json",
+		"phpstan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:^0.12.1 && mv composer.backup composer.json",
 		"test": "php phpunit.phar",
 		"test-setup": "[ ! -f phpunit.phar ] && wget https://phar.phpunit.de/phpunit-8.1.4.phar && mv phpunit-8.1.4.phar phpunit.phar || true",
 		"test-coverage": "php phpunit.phar --log-junit webroot/coverage/unitreport.xml --coverage-html webroot/coverage --coverage-clover webroot/coverage/coverage.xml",
@@ -55,7 +55,6 @@
 		"cs-fix": "phpcbf -v --standard=vendor/fig-r/psr2r-sniffer/PSR2R/ruleset.xml --extensions=php --ignore=/tests/test_files/ src/ tests/ config/"
 	},
 	"prefer-stable": true,
-	"minimum-stability": "dev",
 	"config": {
 		"process-timeout": 600
 	}

+ 2 - 31
docs/Install.md

@@ -7,29 +7,9 @@ Installing the Plugin is pretty much as with every other CakePHP Plugin.
 composer require dereuromark/cakephp-tools
 ```
 
-Details @ https://packagist.org/packages/dereuromark/cakephp-tools
-
-This will load the plugin (within your boostrap file):
-```php
-Plugin::load('Tools');
-```
-or
-```php
-Plugin::loadAll(...);
+The following command can enable the plugin:
 ```
-
-In case you want the Tools bootstrap file included (recommended), you can do that in your `ROOT/config/bootstrap.php` with
-
-```php
-Plugin::load('Tools', ['bootstrap' => true]);
-```
-
-or
-
-```php
-Plugin::loadAll([
-        'Tools' => ['bootstrap' => true]
-]);
+bin/cake plugin load Tools
 ```
 
 ## Namespacing
@@ -70,12 +50,3 @@ $this->loadHelper('Tools.Foo'); // Adding FooHelper
 // In a Controller (deprecated)
 public $helpers = ['Tools.Foo']; // Adding FooHelper
 ```
-
-### Class Alias Shortcuts
-
-For Configure usage especially in view files, you can add this to the bootstrap:
-```php
-class_alias('Cake\Core\Configure', 'Configure');
-```
-This avoids having to add tons of `use` statements at the top of your view ctps.
-But using the helper is preferred and a bit cleaner (`$this->loadHelper('Shim.Configure')`);

+ 5 - 2
docs/Upgrade.md

@@ -1,4 +1,7 @@
 # Migration from 3.x to 4.x
 
-## Session
-- SessionComponent and SessionHelper now need to be handled through request object.
+## ArrayType
+- ArrayType has been moved to Shim plugin
+
+## TestSuite
+The functionality has been moved to Shim plugin

+ 54 - 40
src/Controller/Component/CommonComponent.php

@@ -2,11 +2,11 @@
 
 namespace Tools\Controller\Component;
 
+use Cake\Controller\Component;
 use Cake\Core\Configure;
-use Cake\Event\Event;
+use Cake\Event\EventInterface;
 use Cake\Http\ServerRequest;
 use Cake\Routing\Router;
-use Shim\Controller\Component\Component;
 use Tools\Utility\Utility;
 
 /**
@@ -18,18 +18,32 @@ use Tools\Utility\Utility;
 class CommonComponent extends Component {
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @var \Cake\Controller\Controller
+	 */
+	protected $controller;
+
+	/**
+	 * @param array $config
+	 * @return void
+	 */
+	public function initialize(array $config): void {
+		parent::initialize($config);
+
+		$this->controller = $this->getController();
+	}
+
+	/**
+	 * @param \Cake\Event\EventInterface $event
 	 * @return void
 	 */
-	public function startup(Event $event) {
+	public function startup(EventInterface $event) {
 		if (Configure::read('DataPreparation.notrim')) {
 			return;
 		}
 
-		$request = $this->Controller->getRequest();
-
-		if ($this->Controller->getRequest()->getData()) {
+		$request = $this->controller->getRequest();
 
+		if ($this->controller->getRequest()->getData()) {
 			$newData = Utility::trimDeep($request->getData());
 			foreach ($newData as $k => $v) {
 				if ($request->getData($k) !== $v) {
@@ -50,11 +64,11 @@ class CommonComponent extends Component {
 			}
 		}
 
-		if ($request === $this->Controller->getRequest()) {
+		if ($request === $this->controller->getRequest()) {
 			return;
 		}
 
-		$this->Controller->setRequest($request);
+		$this->controller->setRequest($request);
 	}
 
 	/**
@@ -72,7 +86,7 @@ class CommonComponent extends Component {
 	 * @return string|array
 	 */
 	public function getSafeRedirectUrl($default, $data = null, $key = 'redirect') {
-		$redirectUrl = $data ?: ($this->Controller->getRequest()->getData($key) ?: $this->Controller->getRequest()->getQuery($key));
+		$redirectUrl = $data ?: ($this->controller->getRequest()->getData($key) ?: $this->controller->getRequest()->getQuery($key));
 		if ($redirectUrl && (mb_substr($redirectUrl, 0, 1) !== '/' || mb_substr($redirectUrl, 0, 2) === '//')) {
 			$redirectUrl = null;
 		}
@@ -86,8 +100,8 @@ class CommonComponent extends Component {
 	 * @return array Actions
 	 */
 	public function listActions() {
-		$parentClassMethods = get_class_methods(get_parent_class($this->Controller));
-		$subClassMethods = get_class_methods($this->Controller);
+		$parentClassMethods = get_class_methods(get_parent_class($this->controller));
+		$subClassMethods = get_class_methods($this->controller);
 		$classMethods = array_diff($subClassMethods, $parentClassMethods);
 		foreach ($classMethods as $key => $classMethod) {
 			if (mb_substr($classMethod, 0, 1) === '_') {
@@ -106,7 +120,7 @@ class CommonComponent extends Component {
 	 * @return bool If it is of type POST/PUT/PATCH
 	 */
 	public function isPosted() {
-		return $this->Controller->getRequest()->is(['post', 'put', 'patch']);
+		return $this->controller->getRequest()->is(['post', 'put', 'patch']);
 	}
 
 	/**
@@ -116,7 +130,7 @@ class CommonComponent extends Component {
 	 * @return void
 	 */
 	public function addHelpers(array $helpers) {
-		$this->Controller->viewBuilder()->setHelpers($helpers, true);
+		$this->controller->viewBuilder()->setHelpers($helpers, true);
 	}
 
 	/**
@@ -127,7 +141,7 @@ class CommonComponent extends Component {
 	 * @return mixed
 	 */
 	public function getPassedParam($var, $default = null) {
-		$passed = $this->Controller->getRequest()->getParam('pass');
+		$passed = $this->controller->getRequest()->getParam('pass');
 
 		return isset($passed[$var]) ? $passed[$var] : $default;
 	}
@@ -154,14 +168,14 @@ class CommonComponent extends Component {
 	 * @return mixed URL
 	 */
 	public function currentUrl($asString = false) {
-		$action = $this->Controller->getRequest()->getParam('action');
+		$action = $this->controller->getRequest()->getParam('action');
 
-		$passed = (array)$this->Controller->getRequest()->getParam('pass');
+		$passed = (array)$this->controller->getRequest()->getParam('pass');
 		$url = [
-			'prefix' => $this->Controller->getRequest()->getParam('prefix'),
-			'plugin' => $this->Controller->getRequest()->getParam('plugin'),
+			'prefix' => $this->controller->getRequest()->getParam('prefix'),
+			'plugin' => $this->controller->getRequest()->getParam('plugin'),
 			'action' => $action,
-			'controller' => $this->Controller->getRequest()->getParam('controller'),
+			'controller' => $this->controller->getRequest()->getParam('controller'),
 		];
 		$url = array_merge($passed, $url);
 
@@ -181,10 +195,10 @@ class CommonComponent extends Component {
 	 * @return \Cake\Http\Response
 	 */
 	public function autoRedirect($whereTo, $allowSelf = false, $status = 302) {
-		if ($allowSelf || $this->Controller->referer(null, true) !== $this->Controller->getRequest()->getRequestTarget()) {
-			return $this->Controller->redirect($this->Controller->referer($whereTo, true), $status);
+		if ($allowSelf || $this->controller->referer(null, true) !== $this->controller->getRequest()->getRequestTarget()) {
+			return $this->controller->redirect($this->controller->referer($whereTo, true), $status);
 		}
-		return $this->Controller->redirect($whereTo, $status);
+		return $this->controller->redirect($whereTo, $status);
 	}
 
 	/**
@@ -200,7 +214,7 @@ class CommonComponent extends Component {
 	 * @return \Cake\Http\Response
 	 */
 	public function postRedirect($whereTo, $status = 302) {
-		return $this->Controller->redirect($whereTo, $status);
+		return $this->controller->redirect($whereTo, $status);
 	}
 
 	/**
@@ -213,7 +227,7 @@ class CommonComponent extends Component {
 	 * @return \Cake\Http\Response
 	 */
 	public function autoPostRedirect($whereTo, $conditionalAutoRedirect = true, $status = 302) {
-		$referer = $this->Controller->referer($whereTo, true);
+		$referer = $this->controller->referer($whereTo, true);
 		if (!$conditionalAutoRedirect && !empty($referer)) {
 			return $this->postRedirect($referer, $status);
 		}
@@ -223,7 +237,7 @@ class CommonComponent extends Component {
 			$referer = Router::parseRequest(new ServerRequest(['url' => $referer, 'environment' => ['REQUEST_METHOD' => 'GET']]));
 		}
 
-		if ($conditionalAutoRedirect && !empty($this->Controller->autoRedirectActions) && is_array($referer) && !empty($referer['action'])) {
+		if ($conditionalAutoRedirect && !empty($this->controller->autoRedirectActions) && is_array($referer) && !empty($referer['action'])) {
 			// Be sure that controller offset exists, otherwise you
 			// will run into problems, if you use url rewriting.
 			$refererController = null;
@@ -231,19 +245,19 @@ class CommonComponent extends Component {
 				$refererController = $referer['controller'];
 			}
 			// fixme
-			if (!isset($this->Controller->autoRedirectActions)) {
-				$this->Controller->autoRedirectActions = [];
+			if (!isset($this->controller->autoRedirectActions)) {
+				$this->controller->autoRedirectActions = [];
 			}
 
-			foreach ($this->Controller->autoRedirectActions as $action) {
-				list($controller, $action) = pluginSplit($action);
+			foreach ($this->controller->autoRedirectActions as $action) {
+				[$controller, $action] = pluginSplit($action);
 				if (!empty($controller) && $refererController !== '*' && $refererController !== $controller) {
 					continue;
 				}
-				if (empty($controller) && $refererController !== $this->Controller->getRequest()->getParam('controller')) {
+				if (empty($controller) && $refererController !== $this->controller->getRequest()->getParam('controller')) {
 					continue;
 				}
-				if (!in_array($referer['action'], (array)$this->Controller->autoRedirectActions, true)) {
+				if (!in_array($referer['action'], (array)$this->controller->autoRedirectActions, true)) {
 					continue;
 				}
 				return $this->autoRedirect($whereTo, true, $status);
@@ -264,16 +278,16 @@ class CommonComponent extends Component {
 	public function completeRedirect($url = null, $status = 302) {
 		if ($url === null) {
 			$url = [
-				'plugin' => $this->Controller->getRequest()->getParam('plugin'),
-				'controller' => $this->Controller->getRequest()->getParam('controller'),
-				'action' => $this->Controller->getRequest()->getParam('action'),
-				'_ext' => $this->Controller->getRequest()->getParam('_ext'),
+				'plugin' => $this->controller->getRequest()->getParam('plugin'),
+				'controller' => $this->controller->getRequest()->getParam('controller'),
+				'action' => $this->controller->getRequest()->getParam('action'),
+				'_ext' => $this->controller->getRequest()->getParam('_ext'),
 			];
 		}
 		if (is_array($url)) {
-			$url += $this->Controller->getRequest()->getParam('pass');
+			$url += $this->controller->getRequest()->getParam('pass');
 		}
-		return $this->Controller->redirect($url, $status);
+		return $this->controller->redirect($url, $status);
 	}
 
 	/**
@@ -284,13 +298,13 @@ class CommonComponent extends Component {
 	 * @return void
 	 */
 	public function forceCache($seconds = HOUR) {
-		$response = $this->Controller->getResponse();
+		$response = $this->controller->getResponse();
 
 		$response = $response->withHeader('Cache-Control', 'public, max-age=' . $seconds)
 			->withHeader('Last-modified', gmdate('D, j M Y H:i:s', time()) . ' GMT')
 			->withHeader('Expires', gmdate('D, j M Y H:i:s', time() + $seconds) . ' GMT');
 
-		$this->Controller->setResponse($response);
+		$this->controller->setResponse($response);
 	}
 
 	/**

+ 18 - 18
src/Controller/Component/MobileComponent.php

@@ -2,12 +2,11 @@
 
 namespace Tools\Controller\Component;
 
-use Cake\Controller\Controller;
+use Cake\Controller\Component;
 use Cake\Core\Configure;
-use Cake\Event\Event;
+use Cake\Event\EventInterface;
 use Cake\Routing\Router;
 use RuntimeException;
-use Shim\Controller\Component\Component;
 
 /**
  * A component to easily store mobile in session and serve mobile views to users.
@@ -38,14 +37,14 @@ class MobileComponent extends Component {
 	 *
 	 * @var bool|null
 	 */
-	public $isMobile = null;
+	public $isMobile;
 
 	/**
 	 * Stores the final detection result including user preference.
 	 *
 	 * @var bool|null
 	 */
-	public $setMobile = null;
+	public $setMobile;
 
 	/**
 	 * Default values. Can also be set using Configure.
@@ -73,10 +72,10 @@ class MobileComponent extends Component {
 	}
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @return void
 	 */
-	public function beforeFilter(Event $event) {
+	public function beforeFilter(EventInterface $event) {
 		if ($this->_config['on'] !== 'beforeFilter') {
 			return;
 		}
@@ -95,14 +94,15 @@ class MobileComponent extends Component {
 	 * @return void
 	 */
 	protected function _init() {
-		$mobileOverwrite = $this->Controller->getRequest()->getQuery('mobile');
+		$controller = $this->getController();
+		$mobileOverwrite = $controller->getRequest()->getQuery('mobile');
 
 		if ($mobileOverwrite !== null) {
 			if ($mobileOverwrite === '-1') {
-				$this->Controller->getRequest()->getSession()->delete('User.mobile');
+				$controller->getRequest()->getSession()->delete('User.mobile');
 			} else {
 				$wantsMobile = (bool)$mobileOverwrite;
-				$this->Controller->getRequest()->getSession()->write('User.mobile', (int)$wantsMobile);
+				$controller->getRequest()->getSession()->write('User.mobile', (int)$wantsMobile);
 			}
 		}
 		$this->isMobile();
@@ -125,7 +125,7 @@ class MobileComponent extends Component {
 		if ($this->isMobile === null) {
 			$this->isMobile();
 		}
-		$forceMobile = $this->Controller->getRequest()->getSession()->read('User.mobile');
+		$forceMobile = $this->getController()->getRequest()->getSession()->read('User.mobile');
 
 		if ($forceMobile !== null && !$forceMobile) {
 			$this->setMobile = false;
@@ -148,11 +148,11 @@ class MobileComponent extends Component {
 		if ($this->setMobile) {
 			$urlParams['?']['mobile'] = 0;
 			$url = Router::url($urlParams);
-			$this->Controller->set('desktopUrl', $url);
+			$this->getController()->set('desktopUrl', $url);
 		} else {
 			$urlParams['?']['mobile'] = 1;
 			$url = Router::url($urlParams);
-			$this->Controller->set('mobileUrl', $url);
+			$this->getController()->set('mobileUrl', $url);
 		}
 
 		Configure::write('User.setMobile', (int)$this->setMobile);
@@ -161,8 +161,8 @@ class MobileComponent extends Component {
 			return;
 		}
 
-		$this->Controller->viewBuilder()->setClassName('Theme');
-		$this->Controller->viewBuilder()->setTheme('Mobile');
+		$this->getController()->viewBuilder()->setClassName('Theme');
+		$this->getController()->viewBuilder()->setTheme('Mobile');
 	}
 
 	/**
@@ -198,10 +198,10 @@ class MobileComponent extends Component {
 	public function detect() {
 		// Deprecated - the vendor libs are far more accurate and up to date
 		if (!$this->_config['engine']) {
-			if (isset($this->Controller->RequestHandler)) {
-				return $this->Controller->getRequest()->is('mobile') || $this->Controller->RequestHandler->accepts('wap');
+			if (isset($this->getController()->RequestHandler)) {
+				return $this->getController()->getRequest()->is('mobile') || $this->getController()->RequestHandler->accepts('wap');
 			}
-			return $this->Controller->getRequest()->is('mobile');
+			return $this->getController()->getRequest()->is('mobile');
 		}
 		if (is_callable($this->_config['engine'])) {
 			return call_user_func($this->_config['engine']);

+ 3 - 3
src/Controller/Component/RefererRedirectComponent.php

@@ -3,7 +3,7 @@
 namespace Tools\Controller\Component;
 
 use Cake\Controller\Component;
-use Cake\Event\Event;
+use Cake\Event\EventInterface;
 use Cake\Http\Response;
 
 /**
@@ -24,13 +24,13 @@ class RefererRedirectComponent extends Component {
 	];
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param string|array $url A string or array containing the redirect location
 	 * @param \Cake\Http\Response $response The response object.
 	 *
 	 * @return \Cake\Http\Response|null
 	 */
-	public function beforeRedirect(Event $event, $url, Response $response) {
+	public function beforeRedirect(EventInterface $event, $url, Response $response) {
 		$actions = $this->getConfig('actions');
 		$currentAction = $this->getController()->getRequest()->getParam('action');
 

+ 9 - 9
src/Controller/Component/UrlComponent.php

@@ -2,8 +2,8 @@
 
 namespace Tools\Controller\Component;
 
+use Cake\Controller\Component;
 use Cake\Routing\Router;
-use Shim\Controller\Component\Component;
 
 /**
  * A component for URL topics
@@ -17,7 +17,7 @@ class UrlComponent extends Component {
 	 * @param array $url
 	 * @return array
 	 */
-	public function resetArray(array $url) {
+	public function resetArray(array $url): array {
 		$url += $this->defaults();
 
 		return $url;
@@ -27,7 +27,7 @@ class UrlComponent extends Component {
 	 * @param array $url
 	 * @return array
 	 */
-	public function completeArray(array $url) {
+	public function completeArray(array $url): array {
 		$url = $this->addQueryStrings($url);
 
 		return $url;
@@ -43,7 +43,7 @@ class UrlComponent extends Component {
 	 * @param bool $full If true, the full base URL will be prepended to the result
 	 * @return string Full translated URL with base path.
 	 */
-	public function buildReset($url = null, $full = false) {
+	public function buildReset($url, bool $full = false): string {
 		if (is_array($url)) {
 			$url += $this->defaults();
 		}
@@ -60,7 +60,7 @@ class UrlComponent extends Component {
 	 * @param bool $full If true, the full base URL will be prepended to the result
 	 * @return string Full translated URL with base path.
 	 */
-	public function buildComplete($url = null, $full = false) {
+	public function buildComplete($url, bool $full = false): string {
 		if (is_array($url)) {
 			$url = $this->addQueryStrings($url);
 		}
@@ -81,7 +81,7 @@ class UrlComponent extends Component {
 	 * @param array $options Array of options
 	 * @return string Full translated URL with base path.
 	 */
-	public function build($url = null, array $options = []) {
+	public function build($url = null, array $options = []): string {
 		$defaults = [
 			'fullBase' => false,
 		];
@@ -95,7 +95,7 @@ class UrlComponent extends Component {
 	/**
 	 * @return array
 	 */
-	public function defaults() {
+	public function defaults(): array {
 		return [
 			'prefix' => false,
 			'plugin' => false,
@@ -107,11 +107,11 @@ class UrlComponent extends Component {
 	 *
 	 * @return array
 	 */
-	protected function addQueryStrings(array $url) {
+	protected function addQueryStrings(array $url): array {
 		if (!isset($url['?'])) {
 			$url['?'] = [];
 		}
-		$url['?'] += $this->Controller->getRequest()->getQuery();
+		$url['?'] += $this->getController()->getRequest()->getQuery();
 
 		return $url;
 	}

+ 0 - 43
src/Database/Type/ArrayType.php

@@ -1,43 +0,0 @@
-<?php
-
-namespace Tools\Database\Type;
-
-use Cake\Database\DriverInterface;
-use Cake\Database\Type\BaseType;
-
-/**
- * Do not convert input on marshal().
- */
-class ArrayType extends BaseType {
-
-	/**
-	 * @param mixed $value
-	 * @return mixed
-	 */
-	public function marshal($value) {
-		return $value;
-	}
-
-	/**
-	 * Casts given value from a PHP type to one acceptable by a database.
-	 *
-	 * @param mixed $value Value to be converted to a database equivalent.
-	 * @param \Cake\Database\DriverInterface $driver Object from which database preferences and configuration will be extracted.
-	 * @return mixed Given PHP type casted to one acceptable by a database.
-	 */
-	public function toDatabase($value, DriverInterface $driver) {
-		return $value;
-	}
-
-	/**
-	 * Casts given value from a database type to a PHP equivalent.
-	 *
-	 * @param mixed $value Value to be converted to PHP equivalent
-	 * @param \Cake\Database\DriverInterface $driver Object from which database preferences and configuration will be extracted
-	 * @return mixed Given value casted from a database to a PHP equivalent.
-	 */
-	public function toPHP($value, DriverInterface $driver) {
-		return $value;
-	}
-
-}

+ 38 - 3
src/Error/ErrorHandler.php

@@ -2,6 +2,7 @@
 
 namespace Tools\Error;
 
+use Cake\Error\Debugger;
 use Cake\Error\ErrorHandler as CoreErrorHandler;
 use Cake\Log\Log;
 use Cake\Routing\Router;
@@ -42,14 +43,48 @@ class ErrorHandler extends CoreErrorHandler {
 	 * @param \Psr\Http\Message\ServerRequestInterface|null $request
 	 * @return bool
 	 */
-	protected function _logException(Throwable $exception, ?ServerRequestInterface $request = null): bool {
+	public function logException(Throwable $exception, ?ServerRequestInterface $request = null): bool {
 		if ($this->is404($exception)) {
 			$level = LOG_ERR;
-			Log::write($level, $this->_getMessage($exception), ['404']);
+			Log::write($level, $this->buildMessage($exception), ['404']);
 			return false;
 		}
 
-		return parent::_logException($exception, $request ?? Router::getRequest());
+		return parent::logException($exception, $request ?? Router::getRequest());
+	}
+
+	/**
+	 * @param \Throwable $exception
+	 *
+	 * @return string
+	 */
+	protected function buildMessage(Throwable $exception): string {
+		$error = error_get_last();
+
+		$message = sprintf(
+			'%s (%s): %s in [%s, line %s]',
+			$exception->getMessage(),
+			$exception->getCode(),
+			$error['description'] ?? '',
+			$error['file'] ?? '',
+			$error['line'] ?? ''
+		);
+		if (!empty($this->_config['trace'])) {
+			/** @var string $trace */
+			$trace = Debugger::trace([
+				'start' => 1,
+				'format' => 'log',
+			]);
+
+			$request = Router::getRequest();
+			if ($request) {
+				$message .= $this->getLogger()->getRequestContext($request);
+			}
+			$message .= "\nTrace:\n" . $trace . "\n";
+		}
+		$message .= "\n\n";
+
+		return $message;
 	}
 
 }

+ 0 - 64
src/Error/Middleware/ErrorHandlerMiddleware.php

@@ -1,64 +0,0 @@
-<?php
-
-namespace Tools\Error\Middleware;
-
-use Cake\Error\Middleware\ErrorHandlerMiddleware as CoreErrorHandlerMiddleware;
-use Cake\Log\Log;
-use Psr\Http\Message\ServerRequestInterface;
-use Throwable;
-use Tools\Error\ErrorHandlerTrait;
-
-/**
- * Error handling middleware.
- *
- * Custom ErrorHandler to not mix the 404 exceptions with the rest of "real" errors in the error.log file.
- *
- * All you need to do is in your Application.php file for `new ErrorHandlerMiddleware()`:
- * - Switch `use Cake\Error\Middleware\ErrorHandlerMiddleware;` with `use Tools\Error\Middleware\ErrorHandlerMiddleware;`
- * - Make sure you got the 404 log defined either in your app.php or as Log::config() call.
- *
- * Example config as scoped one:
- * - 'className' => 'Cake\Log\Engine\FileLog',
- * - 'path' => LOGS,
- * - 'file'=> '404',
- * - 'levels' => ['error'],
- * - 'scopes' => ['404']
- *
- * If you don't want the errors to also show up in the debug and error log, make sure you set
- * `'scopes' => false` for those two in your app.php file.
- *
- * In case you need custom 404 mappings for some additional custom exceptions, make use of `log404` option.
- * It will overwrite the current defaults completely.
- */
-class ErrorHandlerMiddleware extends CoreErrorHandlerMiddleware {
-
-	use ErrorHandlerTrait;
-
-	/**
-	 * @param string|callable|null $renderer The renderer or class name
-	 *   to use or a callable factory.
-	 * @param array $config Configuration options to use. If empty, `Configure::read('Error')`
-	 *   will be used.
-	 */
-	public function __construct($renderer = null, array $config = []) {
-		parent::__construct($renderer, $config);
-	}
-
-	/**
-	 * Log an error for the exception if applicable.
-	 *
-	 * @param \Psr\Http\Message\ServerRequestInterface $request The current request.
-	 * @param \Exception $exception The exception to log a message for.
-	 * @return void
-	 */
-	protected function _logException(ServerRequestInterface $request, Throwable $exception): void {
-		if ($this->is404($exception, $request)) {
-			$level = LOG_ERR;
-			Log::write($level, $this->getMessage($request, $exception), ['404']);
-			return;
-		}
-
-		parent::_logException($request, $exception);
-	}
-
-}

+ 3 - 3
src/Form/ContactForm.php

@@ -33,16 +33,16 @@ class ContactForm extends Form {
 	public function validationDefault(Validator $validator): Validator {
 		return $validator
 			->requirePresence('name')
-			->notEmpty('name', __d('tools', 'This field cannot be left empty'))
+			->notEmptyString('name', __d('tools', 'This field cannot be left empty'))
 			->requirePresence('email')
 			->add('email', 'format', [
 					'rule' => 'email',
 					'message' => __d('tools', 'A valid email address is required'),
 			])
 			->requirePresence('subject')
-			->notEmpty('subject', __d('tools', 'This field cannot be left empty'))
+			->notEmptyString('subject', __d('tools', 'This field cannot be left empty'))
 			->requirePresence('body')
-			->notEmpty('body', __d('tools', 'This field cannot be left empty'));
+			->notEmptyString('body', __d('tools', 'This field cannot be left empty'));
 	}
 
 	/**

+ 7 - 2
src/Mailer/Message.php

@@ -15,10 +15,15 @@ use Tools\Utility\Utility;
 class Message extends CakeMessage {
 
 	/**
+	 * @var \Tools\Utility\Mime|null
+	 */
+	protected $_Mime;
+
+	/**
 	 * @param array|null $config Array of configs, or string to load configs from app.php
 	 */
 	public function __construct(?array $config = null) {
-		parent::__construct();
+		parent::__construct($config);
 
 		$xMailer = Configure::read('Config.xMailer');
 		if ($xMailer) {
@@ -366,7 +371,7 @@ class Message extends CakeMessage {
 	protected function _readFile($path) {
 		$context = stream_context_create(
 			['http' => ['header' => 'Connection: close']]);
-		$content = file_get_contents($path, 0, $context);
+		$content = file_get_contents($path, false, $context);
 		if (!$content) {
 			trigger_error('No content found for ' . $path);
 		}

+ 3 - 3
src/Model/Behavior/AfterSaveBehavior.php

@@ -8,7 +8,7 @@ namespace Tools\Model\Behavior;
 
 use ArrayObject;
 use Cake\Datasource\EntityInterface;
-use Cake\Event\Event;
+use Cake\Event\EventInterface;
 use Cake\ORM\Behavior;
 use LogicException;
 
@@ -31,12 +31,12 @@ class AfterSaveBehavior extends Behavior {
 	];
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\Datasource\EntityInterface $entity
 	 * @param \ArrayObject $options
 	 * @return void
 	 */
-	public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options) {
+	public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) {
 		$this->_entity = clone $entity;
 	}
 

+ 9 - 9
src/Model/Behavior/BitmaskedBehavior.php

@@ -5,7 +5,7 @@ namespace Tools\Model\Behavior;
 use ArrayObject;
 use Cake\Database\Expression\Comparison;
 use Cake\Datasource\EntityInterface;
-use Cake\Event\Event;
+use Cake\Event\EventInterface;
 use Cake\ORM\Behavior;
 use Cake\ORM\Query;
 use Cake\Utility\Inflector;
@@ -111,14 +111,14 @@ class BitmaskedBehavior extends Behavior {
 	}
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\ORM\Query $query
 	 * @param \ArrayObject $options
 	 * @param bool $primary
 	 *
 	 * @return void
 	 */
-	public function beforeFind(Event $event, Query $query, ArrayObject $options, $primary) {
+	public function beforeFind(EventInterface $event, Query $query, ArrayObject $options, $primary) {
 		$this->encodeBitmaskConditions($query);
 
 		$field = $this->_config['field'];
@@ -151,12 +151,12 @@ class BitmaskedBehavior extends Behavior {
 	}
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \ArrayObject $data
 	 * @param \ArrayObject $options
 	 * @return void
 	 */
-	public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options) {
+	public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObject $options) {
 		if ($this->_config['on'] !== 'beforeMarshal') {
 			return;
 		}
@@ -164,14 +164,14 @@ class BitmaskedBehavior extends Behavior {
 	}
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\Datasource\EntityInterface $entity
 	 * @param \ArrayObject $options
 	 * @param string $operation
 	 *
 	 * @return void
 	 */
-	public function beforeRules(Event $event, EntityInterface $entity, ArrayObject $options, $operation) {
+	public function beforeRules(EventInterface $event, EntityInterface $entity, ArrayObject $options, $operation) {
 		if ($this->_config['on'] !== 'beforeRules' || !$options['checkRules']) {
 			return;
 		}
@@ -179,12 +179,12 @@ class BitmaskedBehavior extends Behavior {
 	}
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\Datasource\EntityInterface $entity
 	 * @param \ArrayObject $options
 	 * @return void
 	 */
-	public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options) {
+	public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) {
 		if ($this->_config['on'] !== 'beforeSave') {
 			return;
 		}

+ 3 - 3
src/Model/Behavior/ConfirmableBehavior.php

@@ -2,7 +2,7 @@
 
 namespace Tools\Model\Behavior;
 
-use Cake\Event\Event;
+use Cake\Event\EventInterface;
 use Cake\ORM\Behavior;
 use Cake\ORM\Table;
 use Cake\Validation\Validator;
@@ -42,12 +42,12 @@ class ConfirmableBehavior extends Behavior {
 	}
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\Validation\Validator $validator
 	 * @param string $name
 	 * @return void
 	 */
-	public function buildValidator(Event $event, Validator $validator, $name) {
+	public function buildValidator(EventInterface $event, Validator $validator, $name) {
 		$this->build($validator, $name);
 	}
 

+ 8 - 8
src/Model/Behavior/JsonableBehavior.php

@@ -6,12 +6,12 @@ use ArrayObject;
 use Cake\Collection\CollectionInterface;
 use Cake\Database\Type;
 use Cake\Datasource\EntityInterface;
-use Cake\Event\Event;
+use Cake\Event\EventInterface;
 use Cake\ORM\Behavior;
 use Cake\ORM\Entity;
 use Cake\ORM\Query;
 use RuntimeException;
-use Tools\Database\Type\ArrayType;
+use Shim\Database\Type\ArrayType;
 use Tools\Utility\Text;
 
 /**
@@ -41,7 +41,7 @@ class JsonableBehavior extends Behavior {
 	/**
 	 * @var string|false|null
 	 */
-	public $decoded = null;
+	protected $decoded;
 
 	/**
 	 * //TODO: json input/ouput directly, clean
@@ -103,14 +103,14 @@ class JsonableBehavior extends Behavior {
 	/**
 	 * Decode the fields on after find
 	 *
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\ORM\Query $query
 	 * @param \ArrayObject $options
 	 * @param bool $primary
 	 *
 	 * @return void
 	 */
-	public function beforeFind(Event $event, Query $query, ArrayObject $options, $primary) {
+	public function beforeFind(EventInterface $event, Query $query, ArrayObject $options, $primary) {
 		$query->formatResults(function (CollectionInterface $results) {
 			return $results->map(function ($row) {
 				if (!$row instanceof Entity) {
@@ -143,16 +143,16 @@ class JsonableBehavior extends Behavior {
 	/**
 	 * Saves all fields that do not belong to the current Model into 'with' helper model.
 	 *
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\Datasource\EntityInterface $entity
 	 * @param \ArrayObject $options
 	 * @return void
 	 */
-	public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options) {
+	public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) {
 		$fields = $this->_getMappedFields();
 
 		foreach ($fields as $map => $field) {
-			if (!$entity->get($map)) {
+			if ($entity->get($map) === null) {
 				continue;
 			}
 			$val = $entity->get($map);

+ 7 - 7
src/Model/Behavior/PasswordableBehavior.php

@@ -6,7 +6,7 @@ use ArrayObject;
 use Cake\Auth\PasswordHasherFactory;
 use Cake\Core\Configure;
 use Cake\Datasource\EntityInterface;
-use Cake\Event\Event;
+use Cake\Event\EventInterface;
 use Cake\ORM\Behavior;
 use Cake\ORM\Table;
 use RuntimeException;
@@ -217,12 +217,12 @@ class PasswordableBehavior extends Behavior {
 	/**
 	 * Preparing the data
 	 *
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \ArrayObject $data
 	 * @param \ArrayObject $options
 	 * @return void
 	 */
-	public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options) {
+	public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObject $options) {
 		$formField = $this->_config['formField'];
 		$formFieldRepeat = $this->_config['formFieldRepeat'];
 		$formFieldCurrent = $this->_config['formFieldCurrent'];
@@ -269,13 +269,13 @@ class PasswordableBehavior extends Behavior {
 	/**
 	 * Preparing the data
 	 *
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\Datasource\EntityInterface $entity
 	 * @param \ArrayObject $options
 	 * @param string $operation
 	 * @return void
 	 */
-	public function beforeRules(Event $event, EntityInterface $entity, ArrayObject $options, $operation) {
+	public function beforeRules(EventInterface $event, EntityInterface $entity, ArrayObject $options, $operation) {
 		$formField = $this->_config['formField'];
 		$formFieldRepeat = $this->_config['formFieldRepeat'];
 		$formFieldCurrent = $this->_config['formFieldCurrent'];
@@ -300,13 +300,13 @@ class PasswordableBehavior extends Behavior {
 	/**
 	 * Hashing the password and whitelisting
 	 *
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\Datasource\EntityInterface $entity
 	 * @param \ArrayObject $options
 	 * @throws \RuntimeException
 	 * @return void
 	 */
-	public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options) {
+	public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) {
 		$formField = $this->_config['formField'];
 		$field = $this->_config['field'];
 

+ 7 - 7
src/Model/Behavior/SluggedBehavior.php

@@ -5,7 +5,7 @@ namespace Tools\Model\Behavior;
 use ArrayObject;
 use Cake\Core\Configure;
 use Cake\Datasource\EntityInterface;
-use Cake\Event\Event;
+use Cake\Event\EventInterface;
 use Cake\ORM\Behavior;
 use Cake\ORM\Query;
 use Cake\ORM\Table;
@@ -143,7 +143,7 @@ class SluggedBehavior extends Behavior {
 			foreach ($label as $field) {
 				$alias = $this->_table->getAlias();
 				if (strpos($field, '.')) {
-					list($alias, $field) = explode('.', $field);
+					[$alias, $field] = explode('.', $field);
 					if (!$this->_table->$alias->hasField($field)) {
 						throw new RuntimeException('(SluggedBehavior::setup) model `' . $this->_table->$alias->getAlias() . '` is missing the field `' . $field .
 							'` (specified in the setup for table `' . $this->_table->getAlias() . '`) ');
@@ -177,14 +177,14 @@ class SluggedBehavior extends Behavior {
 	/**
 	 * SluggedBehavior::beforeRules()
 	 *
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\Datasource\EntityInterface $entity
 	 * @param \ArrayObject $options
 	 * @param string $operation
 	 *
 	 * @return void
 	 */
-	public function beforeRules(Event $event, EntityInterface $entity, ArrayObject $options, $operation) {
+	public function beforeRules(EventInterface $event, EntityInterface $entity, ArrayObject $options, $operation) {
 		if ($this->_config['on'] === 'beforeRules') {
 			$this->slug($entity);
 		}
@@ -193,12 +193,12 @@ class SluggedBehavior extends Behavior {
 	/**
 	 * SluggedBehavior::beforeSave()
 	 *
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\Datasource\EntityInterface $entity
 	 * @param \ArrayObject $options
 	 * @return void
 	 */
-	public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options) {
+	public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) {
 		if ($this->_config['on'] === 'beforeSave') {
 			$this->slug($entity);
 		}
@@ -399,7 +399,7 @@ class SluggedBehavior extends Behavior {
 		while (($records = $this->_table->find('all', $params)->toArray())) {
 			/** @var \Cake\ORM\Entity $record */
 			foreach ($records as $record) {
-				$record->isNew(true);
+				$record->setNew(true);
 
 				$fields = array_merge([$this->_table->getPrimaryKey(), $this->_config['field']], $this->_config['label']);
 				$options = [

+ 6 - 5
src/Model/Behavior/StringBehavior.php

@@ -5,7 +5,7 @@ namespace Tools\Model\Behavior;
 use ArrayObject;
 use Cake\Datasource\EntityInterface;
 use Cake\Datasource\ResultSetInterface;
-use Cake\Event\Event;
+use Cake\Event\EventInterface;
 use Cake\ORM\Behavior;
 use Cake\ORM\Query;
 
@@ -47,17 +47,18 @@ class StringBehavior extends Behavior {
 	/**
 	 * Decode the fields on after find
 	 *
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\ORM\Query $query
 	 * @param \ArrayObject $options
 	 * @param bool $primary
 	 *
 	 * @return void
 	 */
-	public function beforeFind(Event $event, Query $query, ArrayObject $options, $primary) {
+	public function beforeFind(EventInterface $event, Query $query, ArrayObject $options, $primary) {
 		$query->formatResults(function (ResultSetInterface $results) {
 			return $results->map(function ($row) {
 				$this->processItems($row, 'output');
+
 				return $row;
 			});
 		});
@@ -100,12 +101,12 @@ class StringBehavior extends Behavior {
 	/**
 	 * Saves all fields that do not belong to the current Model into 'with' helper model.
 	 *
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\Datasource\EntityInterface $entity
 	 * @param \ArrayObject $options
 	 * @return void
 	 */
-	public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options) {
+	public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) {
 		$this->processItems($entity, 'input');
 	}
 

+ 7 - 7
src/Model/Behavior/ToggleBehavior.php

@@ -4,7 +4,7 @@ namespace Tools\Model\Behavior;
 
 use ArrayObject;
 use Cake\Datasource\EntityInterface;
-use Cake\Event\Event;
+use Cake\Event\EventInterface;
 use Cake\ORM\Behavior;
 use LogicException;
 
@@ -34,13 +34,13 @@ class ToggleBehavior extends Behavior {
 	];
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\Datasource\EntityInterface $entity
 	 * @param \ArrayObject $options
 	 *
 	 * @return void
 	 */
-	public function afterDelete(Event $event, EntityInterface $entity, ArrayObject $options) {
+	public function afterDelete(EventInterface $event, EntityInterface $entity, ArrayObject $options) {
 		$field = $this->getConfig('field');
 
 		$value = $entity->get($field);
@@ -68,13 +68,13 @@ class ToggleBehavior extends Behavior {
 	}
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\Datasource\EntityInterface $entity
 	 * @param \ArrayObject $options
 	 * @return void
 	 * @throws \LogicException
 	 */
-	public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options) {
+	public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) {
 		$field = $this->getConfig('field');
 
 		if ($entity->isNew() && !$entity->get($field)) {
@@ -97,7 +97,7 @@ class ToggleBehavior extends Behavior {
 	}
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\Datasource\EntityInterface $entity
 	 * @param \ArrayObject $options
 	 *
@@ -105,7 +105,7 @@ class ToggleBehavior extends Behavior {
 	 *
 	 * @throws \LogicException
 	 */
-	public function afterSave(Event $event, EntityInterface $entity, ArrayObject $options) {
+	public function afterSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) {
 		if ($this->_config['on'] !== 'afterSave') {
 			return;
 		}

+ 5 - 5
src/Model/Behavior/TypographicBehavior.php

@@ -9,7 +9,7 @@ namespace Tools\Model\Behavior;
 use ArrayAccess;
 use ArrayObject;
 use Cake\Datasource\EntityInterface;
-use Cake\Event\Event;
+use Cake\Event\EventInterface;
 use Cake\ORM\Behavior;
 
 /**
@@ -122,12 +122,12 @@ class TypographicBehavior extends Behavior {
 	}
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \ArrayObject $data
 	 * @param \ArrayObject $options
 	 * @return bool
 	 */
-	public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options) {
+	public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObject $options) {
 		if ($this->_config['before'] === 'marshal') {
 			$this->process($data);
 		}
@@ -136,12 +136,12 @@ class TypographicBehavior extends Behavior {
 	}
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @param \Cake\Datasource\EntityInterface $entity
 	 * @param \ArrayObject $options
 	 * @return void
 	 */
-	public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options) {
+	public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) {
 		if ($this->_config['before'] === 'save') {
 			$this->process($entity);
 		}

+ 5 - 29
src/Model/Table/Table.php

@@ -24,7 +24,7 @@ class Table extends ShimTable {
 	 * @param array $entities
 	 * @return bool
 	 */
-	public function validateAll(array $entities) {
+	public function validateAll(array $entities): bool {
 		foreach ($entities as $entity) {
 			if ($entity->getErrors()) {
 				return false;
@@ -113,7 +113,7 @@ class Table extends ShimTable {
 	 * @param array $options
 	 * @return \Cake\ORM\Query
 	 */
-	public function getRelatedInUse($tableName, $groupField = null, $type = 'all', $options = []) {
+	public function getRelatedInUse($tableName, $groupField = null, $type = 'all', array $options = []) {
 		if ($groupField === null) {
 			/** @var string $groupField */
 			$groupField = $this->getAssociation($tableName)->getForeignKey();
@@ -285,7 +285,7 @@ class Table extends ShimTable {
 	 * @param array $context
 	 * @return bool Success
 	 */
-	public function validateDateTime($value, $options = [], array $context = []) {
+	public function validateDateTime($value, array $options = [], array $context = []) {
 		if (!$value) {
 			if (!empty($options['allowEmpty'])) {
 				return true;
@@ -376,7 +376,7 @@ class Table extends ShimTable {
 	 * @param array $context
 	 * @return bool Success
 	 */
-	public function validateDate($value, $options = [], array $context = []) {
+	public function validateDate($value, array $options = [], array $context = []) {
 		if (!$value) {
 			if (!empty($options['allowEmpty'])) {
 				return true;
@@ -435,7 +435,7 @@ class Table extends ShimTable {
 	 * @param array $context
 	 * @return bool Success
 	 */
-	public function validateTime($value, $options = [], array $context = []) {
+	public function validateTime($value, array $options = [], array $context = []) {
 		if (!$value) {
 			return false;
 		}
@@ -459,28 +459,4 @@ class Table extends ShimTable {
 		return false;
 	}
 
-	/**
-	 * Validation of Date Fields (>= minDate && <= maxDate)
-	 *
-	 * @param mixed $value
-	 * @param array $options
-	 * - min/max (TODO!!)
-	 * @param array $context
-	 * @return bool
-	 */
-	public function validateDateRange($value, $options = [], array $context = []) {
-	}
-
-	/**
-	 * Validation of Time Fields (>= minTime && <= maxTime)
-	 *
-	 * @param mixed $value
-	 * @param array $options
-	 * - min/max (TODO!!)
-	 * @param array $context
-	 * @return bool
-	 */
-	public function validateTimeRange($value, $options = [], array $context = []) {
-	}
-
 }

+ 1 - 1
src/Model/Table/TokensTable.php

@@ -136,7 +136,7 @@ class TokensTable extends Table {
 		if ($uid) {
 			$options['conditions'][$this->getAlias() . '.user_id'] = $uid;
 		}
-		/** @var \Tools\Model\Entity\Token $tokenEntity */
+		/** @var \Tools\Model\Entity\Token|null $tokenEntity */
 		$tokenEntity = $this->find('all', $options)->first();
 		if (!$tokenEntity) {
 			return null;

+ 2 - 2
src/Shell/InflectShell.php

@@ -41,7 +41,7 @@ class InflectShell extends Shell {
 	/**
 	 * Inflects words
 	 *
-	 * @return bool|int|null
+	 * @return bool|int|null|void
 	 */
 	public function main() {
 		if (!empty($this->args)) {
@@ -168,7 +168,7 @@ class InflectShell extends Shell {
 		}
 
 		$arguments = array_reverse($arguments);
-		if (count($arguments) == 0) {
+		if (count($arguments) === 0) {
 			$words = $this->_getWords();
 		} else {
 			while (count($arguments) > 0) {

+ 3 - 7
src/Utility/Number.php

@@ -70,13 +70,9 @@ class Number extends CakeNumber {
 			}
 			return $default;
 		}
-		if ($formatOptions === false) {
-			$formatOptions = [];
-		} elseif (!is_array($formatOptions)) {
-			$formatOptions = ['places' => $formatOptions];
-		}
-		$options = ['before' => '', 'after' => '', 'places' => 2, 'thousands' => static::$_thousands, 'decimals' => static::$_decimals, 'escape' => false];
-		$options = $formatOptions + $options;
+
+		$defaults = ['before' => '', 'after' => '', 'places' => 2, 'thousands' => static::$_thousands, 'decimals' => static::$_decimals, 'escape' => false];
+		$options = $formatOptions + $defaults;
 
 		if (!empty($options['currency'])) {
 			if (!empty(static::$_symbolRight)) {

+ 7 - 1
src/Utility/Utility.php

@@ -6,6 +6,7 @@ use Cake\Log\Log;
 use Cake\Routing\Router;
 use Cake\Utility\Hash;
 use Exception;
+use InvalidArgumentException;
 use RuntimeException;
 
 /**
@@ -564,7 +565,7 @@ class Utility {
 			}
 
 			if (empty($data) && !empty($stack)) {
-				list($data, $path) = array_pop($stack);
+				[$data, $path] = array_pop($stack);
 				reset($data);
 			}
 		}
@@ -632,6 +633,9 @@ class Utility {
 	 * like array_shift() only for keys and not values
 	 *
 	 * @param array $array keyValuePairs
+	 *
+	 * @throws \InvalidArgumentException
+	 *
 	 * @return string key
 	 */
 	public static function arrayShiftKeys(&$array) {
@@ -639,6 +643,8 @@ class Utility {
 			unset($array[$key]);
 			return $key;
 		}
+
+		throw new InvalidArgumentException('Empty array');
 	}
 
 	/**

+ 0 - 10
src/View/Helper/QrCodeHelper.php

@@ -326,14 +326,4 @@ class QrCodeHelper extends Helper {
 		return $this->options;
 	}
 
-	/**
-	 * 25 => 21x21 (L)
-	 * ...
-	 * 4000 => 547x547 (L)
-	 *
-	 * @return int size
-	 */
-	protected function _findSuitableSize() {
-	}
-
 }

+ 1 - 1
src/View/Helper/TimeHelper.php

@@ -78,7 +78,7 @@ class TimeHelper extends CakeTimeHelper {
 	/**
 	 * Returns a nicely formatted date string for given Datetime string.
 	 *
-	 * @param int|string|\DateTime|null $dateString UNIX timestamp, strtotime() valid string or DateTime object
+	 * @param int|string|\DateTimeInterface|null $dateString UNIX timestamp, strtotime() valid string or DateTime object
 	 * @param string|\DateTimeZone|null $timezone User's timezone string or DateTimeZone object
 	 * @param string|null $locale Locale string.
 	 * @param string|null $default Default string to use when no dateString is given. Use null to allow null as current date.

+ 6 - 3
src/View/Helper/TimelineHelper.php

@@ -141,10 +141,13 @@ function drawVisualization() {
 
 drawVisualization();
 JS;
-		if ($return) {
-			return $script;
+		if (!$return) {
+			$this->_buffer($script, $scriptOptions);
+
+			return null;
 		}
-		$this->_buffer($script, $scriptOptions);
+
+		return $script;
 	}
 
 	/**

+ 3 - 3
src/View/Helper/UrlHelper.php

@@ -55,7 +55,7 @@ class UrlHelper extends CoreUrlHelper {
 	 * @param array $options
 	 * @return string Full translated URL with base path.
 	 */
-	public function buildReset($url = null, array $options = []): string {
+	public function buildReset($url, array $options = []): string {
 		if (is_array($url)) {
 			$url += $this->defaults();
 		}
@@ -72,7 +72,7 @@ class UrlHelper extends CoreUrlHelper {
 	 * @param array $options
 	 * @return string Full translated URL with base path.
 	 */
-	public function buildComplete($url = null, array $options = []): string {
+	public function buildComplete($url, array $options = []): string {
 		if (is_array($url)) {
 			$url = $this->addQueryStrings($url);
 		}
@@ -95,7 +95,7 @@ class UrlHelper extends CoreUrlHelper {
 	 *
 	 * @return array
 	 */
-	protected function addQueryStrings(array $url) {
+	protected function addQueryStrings(array $url): array {
 		if (!isset($url['?'])) {
 			$url['?'] = [];
 		}

+ 1 - 0
tests/Fixture/JsonableCommentsFixture.php

@@ -15,6 +15,7 @@ class JsonableCommentsFixture extends TestFixture {
 		'url' => ['type' => 'string', 'length' => 255, 'null' => false],
 		'title' => ['type' => 'string', 'length' => 255, 'null' => false],
 		'details' => ['type' => 'string', 'length' => 255, 'null' => false],
+		'details_nullable' => ['type' => 'string', 'length' => 255, 'null' => true],
 		'_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]],
 	];
 

+ 1 - 1
tests/TestCase/Auth/MultiColumnAuthenticateTest.php

@@ -13,7 +13,7 @@ class MultiColumnAuthenticateTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.MultiColumnUsers',
 	];
 

+ 1 - 1
tests/TestCase/Controller/Component/MobileComponentTest.php

@@ -18,7 +18,7 @@ class MobileComponentTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'core.Sessions',
 	];
 

+ 1 - 1
tests/TestCase/Controller/ControllerTest.php

@@ -12,7 +12,7 @@ class ControllerTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.ToolsUsers',
 	];
 

+ 1 - 1
tests/TestCase/Controller/ShuntRequestControllerTest.php

@@ -17,7 +17,7 @@ class ShuntRequestControllerTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'core.Sessions',
 	];
 

+ 0 - 60
tests/TestCase/Error/Middleware/ErrorHandlerMiddlewareTest.php

@@ -1,60 +0,0 @@
-<?php
-
-namespace Tools\Test\TestCase\Error\Middleware;
-
-use Cake\Core\Configure;
-use Cake\Http\Exception\NotFoundException;
-use Cake\Http\ServerRequest;
-use Shim\TestSuite\TestCase;
-use Tools\Error\Middleware\ErrorHandlerMiddleware;
-
-class ErrorHandlerMiddlewareTest extends TestCase {
-
-	/**
-	 * @var \Tools\Error\Middleware\ErrorHandlerMiddleware
-	 */
-	protected $errorHandlerMiddleware;
-
-	/**
-	 * @return void
-	 */
-	public function setUp(): void {
-		parent::setUp();
-
-		Configure::write('App.fullBaseUrl', 'http://foo.bar');
-
-		$this->errorHandlerMiddleware = new ErrorHandlerMiddleware();
-	}
-
-	/**
-	 * @return void
-	 */
-	public function tearDown(): void {
-		parent::tearDown();
-
-		unset($this->errorHandlerMiddleware);
-
-		Configure::delete('App.fullBaseUrl');
-	}
-
-	/**
-	 * @return void
-	 */
-	public function test404() {
-		$parameters = [
-			new NotFoundException(),
-			new ServerRequest(),
-		];
-		$result = $this->invokeMethod($this->errorHandlerMiddleware, 'is404', $parameters);
-		$this->assertTrue($result);
-
-		$request = new ServerRequest(['url' => 'http://foo.bar', 'environment' => ['HTTP_REFERER' => 'http://foo.bar/baz']]);
-		$parameters = [
-			new NotFoundException(),
-			$request,
-		];
-		$result = $this->invokeMethod($this->errorHandlerMiddleware, 'is404', $parameters);
-		$this->assertFalse($result);
-	}
-
-}

+ 1 - 1
tests/TestCase/Form/ContactFormTest.php

@@ -9,7 +9,7 @@ class ContactFormTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'core.Posts',
 		'core.Authors',
 		'plugin.Tools.ToolsUsers',

+ 1 - 1
tests/TestCase/Model/Behavior/AfterSaveBehaviorTest.php

@@ -10,7 +10,7 @@ class AfterSaveBehaviorTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'core.Articles',
 	];
 

+ 1 - 1
tests/TestCase/Model/Behavior/BitmaskedBehaviorTest.php

@@ -12,7 +12,7 @@ class BitmaskedBehaviorTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.BitmaskedComments',
 	];
 

+ 1 - 1
tests/TestCase/Model/Behavior/ConfirmableBehaviorTest.php

@@ -10,7 +10,7 @@ class ConfirmableBehaviorTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.SluggedArticles',
 	];
 

+ 36 - 5
tests/TestCase/Model/Behavior/JsonableBehaviorTest.php

@@ -3,6 +3,7 @@
 namespace Tools\Test\TestCase\Model\Behavior;
 
 use Cake\ORM\TableRegistry;
+use PDOException;
 use Shim\TestSuite\TestCase;
 use stdClass;
 
@@ -11,7 +12,7 @@ class JsonableBehaviorTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.JsonableComments',
 	];
 
@@ -75,7 +76,6 @@ class JsonableBehaviorTest extends TestCase {
 	 * @return void
 	 */
 	public function testFieldsWithList() {
-		//echo $this->_header(__FUNCTION__);
 		$this->Comments->removeBehavior('Jsonable');
 		$this->Comments->addBehavior('Tools.Jsonable', ['fields' => ['details'], 'input' => 'list']);
 
@@ -391,13 +391,44 @@ class JsonableBehaviorTest extends TestCase {
 			],
 		];
 		$entity = $this->Comments->newEntity($data);
+
+		$this->expectException(PDOException::class);
+
+		$this->Comments->save($entity);
+	}
+
+	/**
+	 * @return void
+	 */
+	public function testEncodeWithNoParamsComplexContentNullable() {
+		$this->Comments->removeBehavior('Jsonable');
+		$this->Comments->addBehavior('Tools.Jsonable', [
+			'output' => 'array',
+			'fields' => ['details_nullable', 'details'],
+			'encodeParams' => [
+				'options' => 0,
+			],
+		]);
+
+		$data = [
+			'comment' => 'blabla',
+			'url' => 'www.dereuromark.de',
+			'title' => 'param',
+			'details' => [
+			],
+			'details_nullable' => [
+				'foo' => 'bar',
+				'nan' => NAN,
+				'inf' => INF,
+			],
+		];
+		$entity = $this->Comments->newEntity($data);
 		$result = $this->Comments->save($entity);
 		$this->assertTrue((bool)$result);
 
 		$res = $this->Comments->get($entity->id);
-		$expected = [
-		];
-		$this->assertSame($expected, $res->details);
+		$this->assertSame([], $res->details);
+		$this->assertNull($res->details_nullable);
 	}
 
 }

+ 1 - 1
tests/TestCase/Model/Behavior/NeighborBehaviorTest.php

@@ -11,7 +11,7 @@ class NeighborBehaviorTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.Stories',
 	];
 

+ 6 - 1
tests/TestCase/Model/Behavior/PasswordableBehaviorTest.php

@@ -12,7 +12,7 @@ class PasswordableBehaviorTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.ToolsUsers',
 		'plugin.Tools.Roles',
 	];
@@ -23,6 +23,11 @@ class PasswordableBehaviorTest extends TestCase {
 	protected $Users;
 
 	/**
+	 * @var \Cake\Auth\AbstractPasswordHasher
+	 */
+	protected $hasher;
+
+	/**
 	 * SetUp method
 	 *
 	 * @return void

+ 1 - 1
tests/TestCase/Model/Behavior/ResetBehaviorTest.php

@@ -12,7 +12,7 @@ class ResetBehaviorTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.ResetComments',
 	];
 

+ 1 - 1
tests/TestCase/Model/Behavior/SluggedBehaviorTest.php

@@ -20,7 +20,7 @@ class SluggedBehaviorTest extends TestCase {
 	 *
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.SluggedArticles',
 	];
 

+ 1 - 1
tests/TestCase/Model/Behavior/StringBehaviorTest.php

@@ -10,7 +10,7 @@ class StringBehaviorTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.StringComments',
 	];
 

+ 1 - 1
tests/TestCase/Model/Behavior/ToggleBehaviorTest.php

@@ -10,7 +10,7 @@ class ToggleBehaviorTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.ToggleAddresses',
 	];
 

+ 1 - 1
tests/TestCase/Model/Behavior/TypeMapBehaviorTest.php

@@ -10,7 +10,7 @@ class TypeMapBehaviorTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.Data',
 	];
 

+ 1 - 1
tests/TestCase/Model/Behavior/TypographicBehaviorTest.php

@@ -11,7 +11,7 @@ class TypographicBehaviorTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'core.Articles',
 	];
 

+ 1 - 1
tests/TestCase/Model/Entity/EntityTest.php

@@ -10,7 +10,7 @@ class EntityTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.ToolsUsers',
 		'plugin.Tools.Roles',
 	];

+ 1 - 1
tests/TestCase/Model/Table/TableTest.php

@@ -13,7 +13,7 @@ class TableTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'core.Posts',
 		'core.Authors',
 		'plugin.Tools.ToolsUsers',

+ 1 - 1
tests/TestCase/Model/Table/TokensTableTest.php

@@ -10,7 +10,7 @@ class TokensTableTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.Tokens',
 	];
 

+ 3 - 3
tests/TestCase/Utility/NumberTest.php

@@ -18,7 +18,7 @@ class NumberTest extends TestCase {
 	public function setUp(): void {
 		parent::setUp();
 
-		Number::defaultCurrency(false);
+		Number::setDefaultCurrency();
 	}
 
 	/**
@@ -57,7 +57,7 @@ class NumberTest extends TestCase {
 	 * @return void
 	 */
 	public function testMoney() {
-		Number::defaultCurrency('EUR');
+		Number::setDefaultCurrency('EUR');
 
 		$is = Number::money(22.11, ['locale' => 'DE']);
 		$expected = '22,11 €';
@@ -81,7 +81,7 @@ class NumberTest extends TestCase {
 	 * @return void
 	 */
 	public function testCurrency() {
-		Number::defaultCurrency('EUR');
+		Number::setDefaultCurrency('EUR');
 
 		$is = Number::currency(22.11);
 		$expected = '22,11 €';

+ 1 - 1
tests/TestCase/View/Helper/FormatHelperTest.php

@@ -17,7 +17,7 @@ class FormatHelperTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'core.Sessions',
 	];
 

+ 1 - 5
tests/TestCase/View/Helper/NumberHelperTest.php

@@ -110,12 +110,10 @@ class NumberHelperTest extends TestCase {
 	}
 
 	/**
-	 * NumberHelperTest::testCurrency()
-	 *
 	 * @return void
 	 */
 	public function testCurrency() {
-		$is = Number::defaultCurrency();
+		$is = Number::getDefaultCurrency();
 		$this->assertSame('EUR', $is);
 
 		$is = $this->Number->currency(22.2);
@@ -123,8 +121,6 @@ class NumberHelperTest extends TestCase {
 	}
 
 	/**
-	 * NumberHelperTest::testToReadableSize()
-	 *
 	 * @return void
 	 */
 	public function testToReadableSize() {

+ 1 - 1
tests/TestCase/View/Helper/TreeHelperTest.php

@@ -14,7 +14,7 @@ class TreeHelperTest extends TestCase {
 	/**
 	 * @var array
 	 */
-	public $fixtures = [
+	protected $fixtures = [
 		'plugin.Tools.AfterTrees',
 	];
 

+ 5 - 5
tests/test_app/Controller/Component/AppleComponent.php

@@ -2,8 +2,8 @@
 
 namespace TestApp\Controller\Component;
 
-use Cake\Event\Event;
-use Shim\Controller\Component\Component;
+use Cake\Controller\Component;
+use Cake\Event\EventInterface;
 
 /**
  * AppleComponent class
@@ -15,15 +15,15 @@ class AppleComponent extends Component {
 	 *
 	 * @var array
 	 */
-	public $components = ['Banana'];
+	protected $components = ['Banana'];
 
 	/**
 	 * startup method
 	 *
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @return void
 	 */
-	public function startup(Event $event) {
+	public function startup(EventInterface $event) {
 	}
 
 }

+ 4 - 4
tests/test_app/Controller/Component/BananaComponent.php

@@ -2,8 +2,8 @@
 
 namespace TestApp\Controller\Component;
 
-use Cake\Event\Event;
-use Shim\Controller\Component\Component;
+use Cake\Controller\Component;
+use Cake\Event\EventInterface;
 
 /**
  * BananaComponent class
@@ -20,10 +20,10 @@ class BananaComponent extends Component {
 	/**
 	 * startup method
 	 *
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @return void
 	 */
-	public function startup(Event $event) {
+	public function startup(EventInterface $event) {
 		$this->_registry->getController()->bar = 'fail';
 	}
 

+ 6 - 6
tests/test_app/Controller/Component/TestComponent.php

@@ -2,8 +2,8 @@
 
 namespace TestApp\Controller\Component;
 
-use Cake\Event\Event;
-use Shim\Controller\Component\Component;
+use Cake\Controller\Component;
+use Cake\Event\EventInterface;
 
 class TestComponent extends Component {
 
@@ -18,18 +18,18 @@ class TestComponent extends Component {
 	public $isStartup = false;
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @return void
 	 */
-	public function beforeFilter(Event $event) {
+	public function beforeFilter(EventInterface $event) {
 		$this->isInit = true;
 	}
 
 	/**
-	 * @param \Cake\Event\Event $event
+	 * @param \Cake\Event\EventInterface $event
 	 * @return void
 	 */
-	public function startup(Event $event) {
+	public function startup(EventInterface $event) {
 		$this->isStartup = true;
 	}
 

+ 1 - 1
tests/test_app/Model/Table/ToolsUsersTable.php

@@ -11,6 +11,6 @@ class ToolsUsersTable extends Table {
 	 *
 	 * @var array
 	 */
-	public $order = ['name' => 'ASC'];
+	protected $order = ['name' => 'ASC'];
 
 }