updated to Symfony 4.2 (#710)

This commit is contained in:
Kevin Papst
2019-04-21 01:41:08 +02:00
committed by GitHub
parent 32b36f42f0
commit f9c8028ea1
31 changed files with 1010 additions and 616 deletions

View File

@@ -1,5 +1,5 @@
## Description
A clear and concise description of what this pull request changes.
A clear and concise description of what this pull request adds or changes.
## Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
@@ -7,7 +7,7 @@ A clear and concise description of what this pull request changes.
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
## Checklist
- [ ] I have executed `bin/console kimai:phpcs --fix` to make sure my changes adopt the correct code style
- [ ] I have updated the documentation accordingly
- [ ] I ran `bin/console kimai:codestyle --fix` to verify the correct code style
- [ ] I have updated the [documentation](https://github.com/kimai/www.kimai.org/tree/master/_documentation) accordingly
- [ ] I have added tests to cover my changes
- [ ] I agree that this code is used in Kimai and will be published under the [MIT license](https://github.com/kevinpapst/kimai2/blob/master/LICENSE)

View File

@@ -21,7 +21,7 @@ build:
file: 'clover.xml'
format: 'clover'
-
command: 'bin/console kimai:phpcs --checkstyle=checkstyle'
command: 'bin/console kimai:codestyle --checkstyle=checkstyle'
stop_on_failure: true
analysis:
file: 'checkstyle'

View File

@@ -16,6 +16,7 @@ matrix:
include:
- php: 7.1
- php: 7.2
- php: 7.3
before_install:
- phpenv config-rm xdebug.ini

View File

@@ -5,7 +5,7 @@ Send us your ideas, code reviews, pull requests and feature requests to help us
## Pull request rules
- We use PSR-2 with some additional code-style checks (see our [php-cs-fixer config](.php_cs.dist)). You can run `bin/console kimai:phpcs` to check and `bin/console kimai:phpcs --fix` to fix violations.
- We use PSR-2 with some additional code-style checks (see our [php-cs-fixer config](.php_cs.dist)). You can run `bin/console kimai:codestyle` to check and `bin/console kimai:codestyle --fix` to fix violations.
- Add PHPUnit tests for your changes, verify everything still works and execute our test-suites `bin/console kimai:test-unit` and `bin/console kimai:test-integration`.
- If you contribute new files, please add them with the file-header template from below (our chode-style fixer can do that for you).
- With sending in a PR, you accept that your contributions/code will be published under MIT license (see the [LICENSE](LICENSE) file as well).

View File

@@ -31,13 +31,12 @@ before starting the update process. And delete the row `DATABASE_PREFIX` from yo
- API: DateTime objects will be returned including timezone identifier (previously 2019-03-02 14:23 - now 2019-03-02T14:23:00+00:00)
- Plugin mechanism changed: existing Plugins have to be deleted or updated
**Check if you want to apply changes to your `local.yaml`:**
**Apply necessary changes to your `local.yaml`:**
- New permissions are available: `system_configuration`, `system_actions`, `plugins`
**Check if you want to apply changes to your `local.yaml`:**
- New permission is available available: `system_configuration`
New permissions are available:
- `system_configuration` - for accessing the new system configuration screen
- `system_actions` - for the experimental feature to flush your cache from the about screen
- `plugins` - for accessing the new plugins screen
## [0.8.1](https://github.com/kevinpapst/kimai2/releases/tag/0.8.1)
@@ -50,10 +49,15 @@ After you followed the normal update and database migration process (see above),
- Read this [pull request](https://github.com/kevinpapst/kimai2/pull/372) BEFORE you follow the instructions to convert the
timezones in your existing time records with `bin/console kimai:convert-timezone`. Without that, you will end up with wrong times in your database.
Check if you want to apply changes to your `local.yaml`:
**Apply necessary changes to your `local.yaml`:**
- A new boolean setting `kimai.timesheet.rules.allow_future_times` was introduced
- New permissions are available: `view_export, create_export, edit_export_own_timesheet, edit_export_other_timesheet, system_information`
- New permissions are available:
- `view_export` - for the new export feature
- `create_export` - for the new export feature
- `edit_export_own_timesheet` - for the new export feature
- `edit_export_other_timesheet` - for the new export feature
- `system_information` - to see the new about screen
## [0.7](https://github.com/kevinpapst/kimai2/releases/tag/0.7)

View File

@@ -38,3 +38,4 @@ footer.main-footer {
@import 'dashboard';
@import 'navbar';
@import 'daterangepicker';
@import 'tooltip';

36
assets/sass/tooltip.scss Normal file
View File

@@ -0,0 +1,36 @@
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/*
* These styles are not yet used and need some love before actively promoted in the UI.
* They could be used in: templates/macros/widgets.html.twig::label
*/
[data-tooltip] {
position: relative;
overflow: visible;
}
[data-tooltip]:after {
transition: all .2s ease;
content: attr(data-tooltip);
position: absolute;
top: -24px;
left: 50%;
transform: translateX(-50%);
background: $gray;
color: #fff;
padding: 2px 12px;
pointer-events: none;
white-space: nowrap;
font-size: 11px;
line-height: 18px;
border-radius: $border-radius-small;
z-index: 2;
}
[data-tooltip]:not(:hover):after {
opacity: 0;
}

View File

@@ -17,7 +17,6 @@
"ext-pdo": "*",
"ext-zip": "*",
"beberlei/doctrineextensions": "^1.2",
"dama/doctrine-test-bundle": "^5.0",
"doctrine/doctrine-fixtures-bundle": "^3.0",
"erusev/parsedown": "^1.6",
"friendsofsymfony/rest-bundle": "^2.3",
@@ -60,6 +59,7 @@
"white-october/pagerfanta-bundle": "^1.1"
},
"require-dev": {
"dama/doctrine-test-bundle": "^5.0",
"friendsofphp/php-cs-fixer": "^2.10",
"phpunit/phpunit": "^7.0",
"symfony/browser-kit": "^4.0",
@@ -113,7 +113,7 @@
"symfony": {
"id": "01C3FWRDJJEX9K6Y3A4XDFXPBR",
"allow-contrib": true,
"require": "~4.1.0"
"require": "~4.2.0"
}
}
}

1361
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -19,6 +19,7 @@ admin_lte:
collapsed_sidebar: false
# whether the logo collapses or not
mini_sidebar: true
# tabs in the control_sidebar (right screen) can be configured, see:
# https://github.com/kevinpapst/AdminLTEBundle/blob/master/Resources/docs/control_sidebar.md
control_sidebar:

View File

@@ -9,4 +9,4 @@ services:
Twig\Extensions\IntlExtension: ~
#Twig\Extensions\TextExtension: ~
Twig\Extensions\StringLoader:
class: Twig_Extension_StringLoader
class: Twig\Extension\StringLoaderExtension

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
{
"build/app.js": "./app.js?fe004f53e686704f95d7",
"build/app.css": "./app.css?d1c5aa3942706f7bffb181e234e112de",
"build/app.js": "./app.js?79e85ebc5135d84e6896",
"build/app.css": "./app.css?31913e293b00471b96a78048069f0da2",
"build/images/blue@2x.png": "./images/blue@2x.png?2694acfd",
"build/images/blue.png": "./images/blue.png?96f8a905",
"build/fonts/fa-solid-900.woff2": "./fonts/fa-solid-900.woff2?e8a92a29",

View File

@@ -11,8 +11,8 @@ declare(strict_types=1);
namespace App\API;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
abstract class BaseApiController extends Controller
abstract class BaseApiController extends AbstractController
{
}

View File

@@ -18,9 +18,8 @@ use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use Swagger\Annotations as SWG;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class ConfigurationController extends Controller
class ConfigurationController extends BaseApiController
{
/**
* @var ViewHandlerInterface

View File

@@ -16,9 +16,8 @@ use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use Swagger\Annotations as SWG;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class HealthcheckController extends Controller
class HealthcheckController extends BaseApiController
{
/**
* @var ViewHandlerInterface

View File

@@ -18,7 +18,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
/**
* Command used to check and apply the projects coding styles.
*/
class RunCodeSnifferCommand extends Command
class RunCodestyleCommand extends Command
{
/**
* @var BashExecutor
@@ -46,8 +46,8 @@ class RunCodeSnifferCommand extends Command
protected function configure()
{
$this
->setName('kimai:phpcs')
->setDescription('Run PHP_CodeSniffer to check for the projects coding style')
->setName('kimai:codestyle')
->setDescription('Check and fix the projects coding style')
->addOption('fix', null, InputOption::VALUE_NONE, 'Fix all found problems')
->addOption('checkstyle', null, InputOption::VALUE_OPTIONAL, '')
;

View File

@@ -254,7 +254,7 @@ class InvoiceController extends AbstractController
* @Security("is_granted('create_invoice_template')")
*
* @param Request $request
* @param InvoiceTemplate|null $template
* @param InvoiceTemplate|null $copyFrom
* @return \Symfony\Component\HttpFoundation\Response
* @throws \Exception
*/

View File

@@ -27,8 +27,8 @@ class Configuration implements ConfigurationInterface
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('kimai');
$treeBuilder = new TreeBuilder('kimai');
$rootNode = $treeBuilder->getRootNode();
$rootNode
->children()
@@ -68,8 +68,8 @@ class Configuration implements ConfigurationInterface
protected function getTimesheetNode()
{
$builder = new TreeBuilder();
$node = $builder->root('timesheet');
$builder = new TreeBuilder('timesheet');
$node = $builder->getRootNode();
$node
->children()
@@ -185,8 +185,8 @@ class Configuration implements ConfigurationInterface
protected function getInvoiceNode()
{
$builder = new TreeBuilder();
$node = $builder->root('invoice');
$builder = new TreeBuilder('invoice');
$node = $builder->getRootNode();
$node
->addDefaultsIfNotSet()
@@ -208,8 +208,8 @@ class Configuration implements ConfigurationInterface
protected function getLanguagesNode()
{
$builder = new TreeBuilder();
$node = $builder->root('languages');
$builder = new TreeBuilder('languages');
$node = $builder->getRootNode();
$node
->useAttributeAsKey('name', false) // see https://github.com/symfony/symfony/issues/18988
@@ -233,8 +233,8 @@ class Configuration implements ConfigurationInterface
protected function getCalendarNode()
{
$builder = new TreeBuilder();
$node = $builder->root('calendar');
$builder = new TreeBuilder('calendar');
$node = $builder->getRootNode();
$node
->children()
@@ -276,8 +276,8 @@ class Configuration implements ConfigurationInterface
protected function getThemeNode()
{
$builder = new TreeBuilder();
$node = $builder->root('theme');
$builder = new TreeBuilder('theme');
$node = $builder->getRootNode();
$node
->addDefaultsIfNotSet()
@@ -300,8 +300,8 @@ class Configuration implements ConfigurationInterface
protected function getUserNode()
{
$builder = new TreeBuilder();
$node = $builder->root('user');
$builder = new TreeBuilder('user');
$node = $builder->getRootNode();
$node
->addDefaultsIfNotSet()
@@ -320,8 +320,8 @@ class Configuration implements ConfigurationInterface
protected function getWidgetsNode()
{
$builder = new TreeBuilder();
$node = $builder->root('widgets');
$builder = new TreeBuilder('widgets');
$node = $builder->getRootNode();
$node
->requiresAtLeastOneElement()
@@ -351,8 +351,8 @@ class Configuration implements ConfigurationInterface
protected function getDashboardNode()
{
$builder = new TreeBuilder();
$node = $builder->root('dashboard');
$builder = new TreeBuilder('dashboard');
$node = $builder->getRootNode();
$node
->requiresAtLeastOneElement()
@@ -384,8 +384,8 @@ class Configuration implements ConfigurationInterface
protected function getDefaultsNode()
{
$builder = new TreeBuilder();
$node = $builder->root('defaults');
$builder = new TreeBuilder('defaults');
$node = $builder->getRootNode();
$node
->addDefaultsIfNotSet()
@@ -406,8 +406,8 @@ class Configuration implements ConfigurationInterface
protected function getPermissionsNode()
{
$builder = new TreeBuilder();
$node = $builder->root('permissions');
$builder = new TreeBuilder('permissions');
$node = $builder->getRootNode();
$node
->addDefaultsIfNotSet()

View File

@@ -20,12 +20,9 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
*/
class DocumentationLinkExtension extends AbstractTypeExtension
{
/**
* @return string
*/
public function getExtendedType()
public static function getExtendedTypes(): iterable
{
return FormType::class;
return [FormType::class];
}
/**

View File

@@ -34,12 +34,9 @@ class EnhancedChoiceTypeExtension extends AbstractTypeExtension
$this->type = $type;
}
/**
* @return string
*/
public function getExtendedType()
public static function getExtendedTypes(): iterable
{
return EntityType::class;
return [EntityType::class];
}
/**

View File

@@ -34,12 +34,9 @@ class SelectWithApiDataExtension extends AbstractTypeExtension
$this->router = $router;
}
/**
* @return string
*/
public function getExtendedType()
public static function getExtendedTypes(): iterable
{
return EntityType::class;
return [EntityType::class];
}
/**

View File

@@ -29,6 +29,7 @@ class EventExtensions extends AbstractExtension
/**
* @param EventDispatcherInterface $dispatcher
* @param CurrentUser $user
*/
public function __construct(EventDispatcherInterface $dispatcher, CurrentUser $user)
{

View File

@@ -362,6 +362,9 @@
"ref": "9f94d3ea453cd8a3b95db7f82592d7344fe3a76a"
}
},
"symfony/contracts": {
"version": "v1.0.2"
},
"symfony/css-selector": {
"version": "v4.0.4"
},
@@ -509,9 +512,6 @@
"ref": "cda8b550123383d25827705d05a42acf6819fe4e"
}
},
"symfony/security": {
"version": "v4.1.3"
},
"symfony/security-bundle": {
"version": "3.3",
"recipe": {
@@ -521,9 +521,18 @@
"ref": "85834af1496735f28d831489d12ab1921a875e0d"
}
},
"symfony/security-core": {
"version": "v4.2.6"
},
"symfony/security-csrf": {
"version": "v4.0.4"
},
"symfony/security-guard": {
"version": "v4.2.6"
},
"symfony/security-http": {
"version": "v4.2.6"
},
"symfony/serializer": {
"version": "v4.1.2"
},
@@ -572,6 +581,9 @@
"symfony/var-dumper": {
"version": "v4.0.3"
},
"symfony/var-exporter": {
"version": "v4.2.6"
},
"symfony/web-profiler-bundle": {
"version": "3.3",
"recipe": {

View File

@@ -51,29 +51,26 @@
{% set isVisible = activity.project.customer.visible %}
{% endif %}
{% endif %}
{% set label = '' %}
{% if not activity.project is null %}
{% set label = activity.project.customer.name ~ ': ' ~ activity.project.name %}
{% endif %}
{{ macro.label(activity.name, (isVisible ? 'primary' : 'default'), label) }}
{% set type = (isVisible ? 'primary' : 'default') %}
<span class="label label-{{ type }}">{{ activity.name }}</span>
{% endmacro %}
{% macro label_project(project) %}
{% import _self as macro %}
{% set type = 'default' %}
{% if project.visible and project.customer.visible %}
{{ macro.label(project.name, 'primary', project.customer.name) }}
{% else %}
{{ macro.label(project.name, 'default', project.customer.name) }}
{% set type = 'primary' %}
{% endif %}
<span class="label label-{{ type }}">{{ project.name }}</span>
{% endmacro %}
{% macro label_customer(customer) %}
{% import _self as macro %}
{% set type = 'default' %}
{% if customer.visible %}
{{ macro.label(customer.name, 'primary') }}
{% else %}
{{ macro.label(customer.name, 'default') }}
{% set type = 'primary' %}
{% endif %}
<span class="label label-{{ type }}">{{ customer.name }}</span>
{% endmacro %}
{% macro badge_counter(count, url) %}
@@ -86,7 +83,7 @@
{% macro label(title, type, tooltip) %}
{# success, warning, danger, primary #}
<span {% if tooltip %}title="{{ tooltip }}" {% endif %}class="label label-{{ type|default('success') }}">{{ title|trans }}</span>
<span {% if tooltip %}data-tooltip="{{ tooltip }}" {% endif %}class="label label-{{ type|default('success') }}">{{ title|trans }}</span>
{% endmacro %}
{% macro badge(title, color) %}

View File

@@ -6,7 +6,7 @@
</a>
<ul class="dropdown-menu">
<li class="header">
{{ 'active.entries'|transchoice(entries|length) }}
{{ 'active.entries'|trans({'%count%':(entries|length)}) }}
</li>
<li>
{% if entries is not empty %}

View File

@@ -5,7 +5,7 @@
<span class="label label-success">{{ entries|length }}</span>
</a>
<ul class="dropdown-menu">
<li class="header">{{ 'recent.activities'|transchoice(entries|length) }}</li>
<li class="header">{{ 'recent.activities'|trans({'%count%':(entries|length)}) }}</li>
<li>
<ul class="menu">
{% for timesheet in entries %}

View File

@@ -17,6 +17,7 @@
{% if entries.count == 0 %}
{{ widgets.callout('warning', 'error.no_entries_found') }}
{% else %}
{% set canSeeRate = is_granted('view_rate_own_timesheet') %}
{% set columns = {'date': ''} %}
{% if not duration_only %}
@@ -25,7 +26,7 @@
{% set columns = columns|merge({'duration': ''}) %}
{% if is_granted('view_rate_own_timesheet') %}
{% if canSeeRate %}
{% set columns = columns|merge({'rate': 'hidden-xs'}) %}
{% endif %}
@@ -50,7 +51,7 @@
{% set day = entry.begin|date_short %}
{% endif %}
{% if showSummary and day is not same as(entry.begin|date_short) %}
{{ timesheet.summary(day, dayDuration, dayRate, columns) }}
{{ timesheet.summary(day, dayDuration, dayRate, columns, canSeeRate) }}
{% set day = entry.begin|date_short %}
{% set dayDuration = 0 %}
{% set dayRate = {} %}
@@ -67,7 +68,7 @@
<td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'endtime') }}">{{ entry.end|time }}</td>
{% endif %}
<td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'duration') }}">{{ entry.duration|duration }}</td>
{% if is_granted('view_rate', entry) %}
{% if canSeeRate %}
<td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'rate') }}">{{ entry.rate|money(entry.project.customer.currency) }}</td>
{% endif %}
{% else %}
@@ -75,7 +76,7 @@
<td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'endtime') }}">&dash;</td>
{% endif %}
<td class="text-nowrap {{ tables.data_table_column_class(tableName, columns, 'duration') }}"><i>{{ entry|duration }}</i></td>
{% if is_granted('view_rate', entry) %}
{% if canSeeRate %}
<td class="{{ tables.data_table_column_class(tableName, columns, 'rate') }}">&dash;</td>
{% endif %}
{% endif %}
@@ -98,7 +99,7 @@
{% endfor %}
{% if showSummary %}
{{ timesheet.summary(day, dayDuration, dayRate, columns) }}
{{ timesheet.summary(day, dayDuration, dayRate, columns, canSeeRate) }}
{% endif %}
{{ tables.data_table_footer(entries, 'timesheet_paginated') }}
@@ -120,13 +121,13 @@
</script>
{% endblock %}
{% macro summary(day, duration, dayRates, columns) %}
{% macro summary(day, duration, dayRates, columns, canSeeRate) %}
<tr class="summary info">
<td class="text-nowrap">{{ day }}</td>
<td></td>
<td></td>
<td class="text-nowrap">{{ duration|duration }}</td>
{% if is_granted('view_rate_own_timesheet') %}
{% if canSeeRate %}
<td class="text-nowrap">
{% for currency, rate in dayRates %}
{{ rate|money(currency) }}

View File

@@ -10,16 +10,16 @@
namespace App\Tests\Command;
use App\Command\BashResult;
use App\Command\RunCodeSnifferCommand;
use App\Command\RunCodestyleCommand;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Console\Tester\CommandTester;
/**
* @coversDefaultClass \App\Command\RunCodeSnifferCommand
* @coversDefaultClass \App\Command\RunCodestyleCommand
* @group integration
*/
class RunCodeSnifferCommandTest extends KernelTestCase
class RunCodestyleCommandTest extends KernelTestCase
{
/**
* @var Application
@@ -41,7 +41,7 @@ class RunCodeSnifferCommandTest extends KernelTestCase
$this->directory = realpath(__DIR__ . '/../../');
$this->executor = new TestBashExecutor($this->directory);
$this->application->add(new RunCodeSnifferCommand($this->executor, $this->directory));
$this->application->add(new RunCodestyleCommand($this->executor, $this->directory));
}
public function testSuccessCommandNoOptions()
@@ -68,7 +68,7 @@ class RunCodeSnifferCommandTest extends KernelTestCase
$result = new BashResult(0, 'FooBar');
$this->executor->setResult($result);
$command = $this->application->find('kimai:phpcs');
$command = $this->application->find('kimai:codestyle');
$commandTester = new CommandTester($command);
$inputs = array_merge(['command' => $command->getName()], $options);
$commandTester->execute($inputs);
@@ -85,7 +85,7 @@ class RunCodeSnifferCommandTest extends KernelTestCase
$result = new BashResult(1, 'BarFoo');
$this->executor->setResult($result);
$command = $this->application->find('kimai:phpcs');
$command = $this->application->find('kimai:codestyle');
$commandTester = new CommandTester($command);
$inputs = array_merge(['command' => $command->getName()], ['--fix' => true]);
$commandTester->execute($inputs);

View File

@@ -918,7 +918,7 @@
-->
<trans-unit id="active.entries">
<source>active.entries</source>
<target>Sie haben %count% aktiven Eintrag|Sie haben %count% aktive Einträge</target>
<target>Sie haben einen aktiven Eintrag|Sie haben %count% aktive Einträge</target>
</trans-unit>
<trans-unit id="timesheet.all">
<source>timesheet.all</source>