Support for PHP 8 (#2158)

painful 66 commits later: required PHP version bumped to 7.3, plugin updates using migrations necessary!
This commit is contained in:
Kevin Papst
2021-05-31 14:53:22 +02:00
committed by GitHub
parent df6bd30d03
commit 4859ac8ecb
21 changed files with 1157 additions and 1283 deletions

View File

@@ -1,4 +1,4 @@
name: CI
name: Coverage
on:
pull_request: null
push:
@@ -19,9 +19,9 @@ jobs:
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
strategy:
matrix:
php: ['7.3']
php: ['7.4']
name: Coverage - PHP ${{ matrix.php }}
name: PHP ${{ matrix.php }}
steps:
- uses: actions/checkout@v2
- uses: shivammathur/setup-php@v2

View File

@@ -1,4 +1,4 @@
name: CI
name: Linting
on:
pull_request: null
push:
@@ -9,9 +9,9 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php: ['7.4']
php: ['7.4', '8.0']
name: Linting - PHP ${{ matrix.php }}
name: PHP ${{ matrix.php }}
steps:
- uses: actions/checkout@v2
- uses: shivammathur/setup-php@v2
@@ -22,7 +22,7 @@ jobs:
tools: cs2pr:1.1.0
- run: composer install --no-progress
- run: composer validate --strict
- run: vendor/bin/php-cs-fixer fix --dry-run --verbose --config=.php_cs.dist --using-cache=no --show-progress=none --format=checkstyle | cs2pr
- run: vendor/bin/php-cs-fixer fix --dry-run --verbose --config=.php-cs-fixer.dist.php --using-cache=no --show-progress=none --format=checkstyle | cs2pr
- run: vendor/bin/phpstan analyse src -c phpstan.neon --level=5 --no-progress --error-format=checkstyle | cs2pr
- run: vendor/bin/phpstan analyse tests -c tests/phpstan.neon --level=5 --no-progress --error-format=checkstyle | cs2pr
- run: composer kimai:code-lint

View File

@@ -1,4 +1,4 @@
name: CI
name: Tests
on:
pull_request: null
push:
@@ -19,9 +19,9 @@ jobs:
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
strategy:
matrix:
php: ['7.2', '7.3', '7.4']
php: ['7.3', '7.4', '8.0']
name: Tests - PHP ${{ matrix.php }}
name: PHP ${{ matrix.php }}
steps:
- uses: actions/checkout@v2
- uses: shivammathur/setup-php@v2
@@ -48,6 +48,7 @@ jobs:
MAILER_URL: null://localhost
- name: Run migrations on MySQL
run: |
bin/console doctrine:database:drop --if-exists --force -n
bin/console doctrine:database:create --if-not-exists -n
bin/console doctrine:migrations:migrate -n
bin/console doctrine:migrations:migrate first -n

1
.gitignore vendored
View File

@@ -56,6 +56,7 @@ translations/branding.en.xlf
###> friendsofphp/php-cs-fixer ###
.php_cs
.php_cs.cache
.php-cs-fixer.cache
###< friendsofphp/php-cs-fixer ###
###> symfony/phpunit-bridge ###

View File

@@ -7,7 +7,8 @@ For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
COMMENT;
return PhpCsFixer\Config::create()
$fixer = new PhpCsFixer\Config();
$fixer
->setRiskyAllowed(true)
->setRules([
'encoding' => true,
@@ -19,7 +20,7 @@ return PhpCsFixer\Config::create()
'function_declaration' => true,
'indentation_type' => true,
'line_ending' => true,
'lowercase_constants' => true,
'constant_case' => ['case' => 'lower'],
'lowercase_keywords' => true,
'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'],
'header_comment' => ['header' => $fileHeaderComment, 'separate' => 'both'],
@@ -46,7 +47,7 @@ return PhpCsFixer\Config::create()
'statements' => ['return'],
],
'cast_spaces' => true,
'class_attributes_separation' => ['elements' => ['method']],
'class_attributes_separation' => ['elements' => ['method' => 'one']],
'concat_space' => ['spacing' => 'one'],
'declare_equal_normalize' => true,
'function_typehint_space' => true,
@@ -100,7 +101,7 @@ return PhpCsFixer\Config::create()
],
'phpdoc_annotation_without_dot' => true,
'phpdoc_indent' => true,
'phpdoc_inline_tag' => true,
'phpdoc_inline_tag_normalizer' => true,
'phpdoc_no_access' => true,
'phpdoc_no_alias_tag' => true,
'phpdoc_no_empty_return' => false,
@@ -130,7 +131,7 @@ return PhpCsFixer\Config::create()
'standardize_increment' => true,
'standardize_not_equals' => true,
'ternary_operator_spaces' => true,
'trailing_comma_in_multiline_array' => false,
'trailing_comma_in_multiline' => false,
'trim_array_spaces' => true,
'unary_operator_spaces' => true,
'whitespace_after_comma_in_array' => true,
@@ -163,3 +164,5 @@ return PhpCsFixer\Config::create()
)
->setFormat('checkstyle')
;
return $fixer;

View File

@@ -8,6 +8,18 @@ you can upgrade your Kimai installation to the latest stable release.
Check below if there are more version specific steps required, which need to be executed after the normal update process.
Perform EACH version specific task between your version and the new one, otherwise you risk data inconsistency or a broken installation.
## [1.15](https://github.com/kevinpapst/kimai2/releases/tag/1.15)
**ATTENTION**
- This release bumps the minimum required [PHP version to 7.3](https://www.kimai.org/blog/2021/php8-support-php72-dropped/)
- All plugins that use own databases need to be updated as well
PHP 8 compatibility forced to upgrade MANY libraries, including but not limited to:
- Doctrine Migrations, whose new major version forces the plugin updates
- Gedmo v3 (which include BC breaks in definitions)
- Doctrine DBAL and others, which required PHP 7.3 as well
## [1.14](https://github.com/kevinpapst/kimai2/releases/tag/1.14)
**CRITICAL BC break**: SQLite support was removed. If you are using SQLite, you have to [read this blog post](https://www.kimai.org/blog/2021/sqlite-and-ftp-support-removed/) and migrate to MySQL/MariaDB first!

View File

@@ -10,7 +10,7 @@
}
],
"require": {
"php": "^7.2.9",
"php": ">=7.3",
"ext-gd": "*",
"ext-intl": "*",
"ext-json": "*",
@@ -21,29 +21,29 @@
"beberlei/doctrineextensions": "^1.2",
"composer/package-versions-deprecated": "^1.8",
"doctrine/doctrine-bundle": "^2.0",
"doctrine/doctrine-migrations-bundle": "^2.1",
"doctrine/orm": "^2.7",
"doctrine/doctrine-migrations-bundle": "^3.0",
"doctrine/orm": "^2.8",
"erusev/parsedown": "^1.6",
"friendsofsymfony/rest-bundle": "^3.0",
"gedmo/doctrine-extensions": "^2.4",
"gedmo/doctrine-extensions": "^3.0",
"handcraftedinthealps/rest-routing-bundle": "^1.0",
"hslavich/oneloginsaml-bundle": "^1.4",
"jms/metadata": "^2.0",
"jms/serializer-bundle": "^3.2",
"jms/serializer-bundle": "^3.9",
"kevinpapst/adminlte-bundle": "^3.3",
"kimai/user-bundle": "^1.1",
"laravolt/avatar": "^3.0",
"kimai/user-bundle": "^2.0",
"laravolt/avatar": "^4.0",
"league/csv": "^9.4",
"league/html-to-markdown": "^4.9",
"league/html-to-markdown": "^5.0",
"mpdf/mpdf": "^8.0",
"nelmio/api-doc-bundle": "^3.2",
"nelmio/cors-bundle": "^1.5",
"nelmio/cors-bundle": "^2.0",
"onelogin/php-saml": "^3.4",
"pagerfanta/pagerfanta": "^2.1",
"phpoffice/phpspreadsheet": "^1.16",
"phpoffice/phpword": "^0.17",
"phpoffice/phpword": "^0.18",
"psr/log": "^1.1",
"sensio/framework-extra-bundle": "^5.2",
"sensio/framework-extra-bundle": "^6.0",
"symfony/amazon-mailer": "^4.4",
"symfony/asset": "^4.4",
"symfony/console": "^4.4",
@@ -79,7 +79,7 @@
"require-dev": {
"dama/doctrine-test-bundle": "^6.0",
"doctrine/doctrine-fixtures-bundle": "^3.2",
"friendsofphp/php-cs-fixer": "^2.10",
"friendsofphp/php-cs-fixer": "^3.0",
"fzaninotto/faker": "^1.8",
"phpstan/phpstan": "^0.12",
"phpstan/phpstan-doctrine": "^0.12",
@@ -100,10 +100,10 @@
"type": "artifact",
"url": "var/packages/"
}
],
],
"config": {
"platform": {
"php": "7.2.9"
"php": "7.3"
},
"preferred-install": {
"*": "dist"

2217
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,6 @@ doctrine:
default_connection: default
connections:
default:
override_url: true
# existing migrations will fail if the schema filter is activated
#schema_filter: ~^(?!(bundle_migration_|kimai2_sessions))~
url: '%env(DATABASE_URL)%'

View File

@@ -1,4 +1,7 @@
doctrine_migrations:
storage:
table_storage:
table_name: 'migration_versions'
migrations_paths:
# namespace is arbitrary but should be different from App\Migrations
# as migrations classes should NOT be autoloaded

View File

@@ -68,7 +68,7 @@ final class ReloadCommand extends Command
// many users execute the bin/console command from arbitrary locations
$path = getcwd();
\chdir($this->getRootDirectory());
chdir($this->getRootDirectory());
try {
$command = $this->getApplication()->find('lint:yaml');

View File

@@ -9,6 +9,7 @@
namespace App\Controller;
use Composer\InstalledVersions;
use PackageVersions\Versions;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpFoundation\Response;
@@ -111,26 +112,37 @@ class DoctorController extends AbstractController
private function getComposerPackages(): array
{
$packages = [];
$versions = [];
if (class_exists('Composer\Versions')) {
// TODO composer 2
if (class_exists(InstalledVersions::class)) {
$rootPackage = InstalledVersions::getRootPackage()['name'];
foreach (InstalledVersions::getInstalledPackages() as $package) {
$versions[$package] = InstalledVersions::getPrettyVersion($package);
}
} else {
$packages = Versions::VERSIONS;
// @deprecated since 1.14, will be removed with 2.0
$rootPackage = Versions::rootPackageName();
foreach (Versions::VERSIONS as $name => $version) {
$versions[$name] = explode('@', $version)[0];
}
}
// remove kimai from the package list
$packages = array_filter($packages, function ($name) {
if ($name === Versions::ROOT_PACKAGE_NAME) {
$versions = array_filter($versions, function ($version, $name) use ($rootPackage) {
if ($name === $rootPackage) {
return false;
}
if ($version === null || $version === '*') {
return false;
}
return true;
}, ARRAY_FILTER_USE_KEY);
}, ARRAY_FILTER_USE_BOTH);
ksort($packages);
ksort($versions);
return $packages;
return $versions;
}
private function getLoadedExtensions()

View File

@@ -9,51 +9,36 @@
namespace App\Doctrine;
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration as BaseAbstractMigration;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Base class for all Doctrine migrations.
*
* @codeCoverageIgnore
*/
abstract class AbstractMigration extends BaseAbstractMigration implements ContainerAwareInterface
abstract class AbstractMigration extends BaseAbstractMigration
{
/**
* @var ContainerInterface
*/
private $container;
/**
* @param ContainerInterface $container
*/
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
/**
* @return ContainerInterface
*/
public function getContainer()
{
return $this->container;
}
/**
* @param string $name
* @return string
* @deprecated since 0.9 - will be removed with 2.0
*/
protected function getTableName($name)
{
@trigger_error('AbstractMigration::getTableName() is deprecated and will be removed with 2.0', E_USER_DEPRECATED);
return 'kimai2_' . $name;
}
/**
* @see https://github.com/doctrine/migrations/issues/1104
*/
public function isTransactional(): bool
{
return false;
}
/**
* @deprecated since 1.14 - will be removed with 2.0
*/
@@ -82,7 +67,7 @@ abstract class AbstractMigration extends BaseAbstractMigration implements Contai
/**
* @param Schema $schema
* @throws DBALException
* @throws Exception
*/
public function preUp(Schema $schema): void
{
@@ -91,7 +76,7 @@ abstract class AbstractMigration extends BaseAbstractMigration implements Contai
/**
* @param Schema $schema
* @throws DBALException
* @throws Exception
*/
public function preDown(Schema $schema): void
{
@@ -101,7 +86,7 @@ abstract class AbstractMigration extends BaseAbstractMigration implements Contai
/**
* Abort the migration is the current platform is not supported.
*
* @throws DBALException
* @throws Exception
*/
protected function abortIfPlatformNotSupported()
{
@@ -128,27 +113,13 @@ abstract class AbstractMigration extends BaseAbstractMigration implements Contai
/**
* @return string
* @throws DBALException
* @throws Exception
*/
protected function getPlatform()
{
return $this->connection->getDatabasePlatform()->getName();
}
/**
* Call me like this:
* $schema = $this->getClassMetaData(User::class);
*
* @param string $entityName
* @return ClassMetadata
*/
protected function getClassMetaData($entityName)
{
$em = $this->getContainer()->get('doctrine')->getManager();
return $em->getClassMetadata($entityName);
}
/**
* @deprecated since 1.14 - will be removed with 2.0
*/

View File

@@ -40,7 +40,7 @@ class DurationStringToSecondsTransformer implements DataTransformerInterface
{
try {
return $this->formatter->format($intToFormat);
} catch (\Exception $e) {
} catch (\Exception | \TypeError $e) {
throw new TransformationFailedException($e->getMessage());
}
}

View File

@@ -93,7 +93,7 @@ class LdapUserProvider implements UserProviderInterface
public function supportsClass($class)
{
return $class === User::class || $class === 'App\Entity\User';
return $class === User::class;
}
/**

View File

@@ -11,7 +11,6 @@ namespace App\Repository;
use App\Entity\Role;
use App\Entity\RolePermission;
use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\EntityRepository;
/**
@@ -38,6 +37,6 @@ class RolePermissionRepository extends EntityRepository
$qb->select('r.name as role,rp.permission,rp.allowed')
->leftJoin('rp.role', 'r');
return $qb->getQuery()->execute([], AbstractQuery::HYDRATE_ARRAY);
return $qb->getQuery()->getArrayResult();
}
}

View File

@@ -72,6 +72,6 @@ final class DoctrineUserProvider implements UserProviderInterface
*/
public function supportsClass($class)
{
return $class === User::class || $class === 'App\Entity\User';
return $class === User::class;
}
}

View File

@@ -51,7 +51,7 @@ final class LocaleHelper
$value = 0;
}
return $this->getNumberFormatter()->format($value);
return $this->getNumberFormatter()->format((float) $value);
}
/**

View File

@@ -99,9 +99,6 @@
"doctrine/persistence": {
"version": "v1.0.0"
},
"doctrine/reflection": {
"version": "v1.0.0"
},
"doctrine/sql-formatter": {
"version": "1.1.1"
},
@@ -156,9 +153,15 @@
"illuminate/cache": {
"version": "v6.0.4"
},
"illuminate/collections": {
"version": "v8.44.0"
},
"illuminate/contracts": {
"version": "v6.0.4"
},
"illuminate/macroable": {
"version": "v8.44.0"
},
"illuminate/support": {
"version": "v6.0.4"
},
@@ -189,6 +192,9 @@
"laminas/laminas-code": {
"version": "3.4.1"
},
"laminas/laminas-escaper": {
"version": "2.7.0"
},
"laminas/laminas-eventmanager": {
"version": "3.2.1"
},
@@ -267,9 +273,6 @@
"paragonie/random_compat": {
"version": "v2.0.17"
},
"pclzip/pclzip": {
"version": "2.8.2"
},
"phar-io/manifest": {
"version": "1.0.1"
},
@@ -291,9 +294,6 @@
"phpdocumentor/type-resolver": {
"version": "0.4.0"
},
"phpoffice/common": {
"version": "0.2.9"
},
"phpoffice/phpspreadsheet": {
"version": "1.4.0"
},
@@ -816,9 +816,6 @@
"zendframework/zend-code": {
"version": "3.3.0"
},
"zendframework/zend-escaper": {
"version": "2.6.0"
},
"zendframework/zend-eventmanager": {
"version": "3.2.0"
},

View File

@@ -54,8 +54,7 @@ class UpdateCommandTest extends KernelTestCase
self::assertStringContainsString('Kimai updates running', $result);
// make sure migrations run always
self::assertStringContainsString('Application Migrations', $result);
self::assertStringContainsString('No migrations to execute.', $result);
self::assertStringContainsString('[OK] Already at the latest version ("DoctrineMigrations\\', $result);
self::assertStringContainsString(
sprintf('[OK] Congratulations! Successfully updated Kimai to version %s', Constants::VERSION),

View File

@@ -11,7 +11,6 @@ namespace App\Tests\Ldap;
use App\Entity\User;
use App\Ldap\LdapDriver;
use App\Ldap\LdapDriverException;
use Laminas\Ldap\Exception\LdapException;
use Laminas\Ldap\Ldap;
use PHPUnit\Framework\TestCase;
@@ -61,21 +60,6 @@ class LdapDriverTest extends TestCase
$result = $sut->search('', '', []);
self::assertEquals(['count' => 3, 1, 2, 3], $result);
}
public function testSearchException()
{
$this->expectException(LdapDriverException::class);
$this->expectExceptionMessage('An error occurred with the search operation.');
$zendLdap = $this->getMockBuilder(Ldap::class)->disableOriginalConstructor()->onlyMethods(['bind', 'searchEntries'])->getMock();
$zendLdap->expects($this->once())->method('bind');
$zendLdap->expects($this->once())->method('searchEntries')->willThrowException(
new LdapException($zendLdap, '', LdapException::LDAP_SERVER_DOWN)
);
$sut = new TestLdapDriver($zendLdap);
$sut->search('', '', []);
}
}
class TestLdapDriver extends LdapDriver