* use php-cs-fixer instead of phpcodesniffer * updated scrutinizer config * adjusted code yules to all files * updated CONTRIBUTING guidelines
This commit is contained in:
138
.php_cs.dist
138
.php_cs.dist
@@ -2,7 +2,141 @@
|
||||
|
||||
return PhpCsFixer\Config::create()
|
||||
->setRules([
|
||||
'@Symfony' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'encoding' => true,
|
||||
'full_opening_tag' => true,
|
||||
'blank_line_after_namespace' => true,
|
||||
'braces' => true,
|
||||
'class_definition' => true,
|
||||
'elseif' => true,
|
||||
'function_declaration' => true,
|
||||
'indentation_type' => true,
|
||||
'line_ending' => true,
|
||||
'lowercase_constants' => true,
|
||||
'lowercase_keywords' => true,
|
||||
'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'],
|
||||
'no_break_comment' => true,
|
||||
'no_closing_tag' => true,
|
||||
'no_spaces_after_function_name' => true,
|
||||
'no_spaces_inside_parenthesis' => true,
|
||||
'no_trailing_whitespace' => true,
|
||||
'no_trailing_whitespace_in_comment' => true,
|
||||
'single_blank_line_at_eof' => true,
|
||||
'single_class_element_per_statement' => ['elements' => ['property']],
|
||||
'single_import_per_statement' => true,
|
||||
'single_line_after_imports' => true,
|
||||
'switch_case_semicolon_to_colon' => true,
|
||||
'switch_case_space' => true,
|
||||
'array_syntax' => [
|
||||
'syntax' => 'short'
|
||||
],
|
||||
'binary_operator_spaces' => true,
|
||||
'blank_line_after_opening_tag' => true,
|
||||
'blank_line_before_statement' => [
|
||||
'statements' => ['return'],
|
||||
],
|
||||
'cast_spaces' => true,
|
||||
'class_attributes_separation' => ['elements' => ['method']],
|
||||
'concat_space' => ['spacing' => 'one'],
|
||||
'declare_equal_normalize' => true,
|
||||
'function_typehint_space' => true,
|
||||
'include' => true,
|
||||
'lowercase_cast' => true,
|
||||
'lowercase_static_reference' => true,
|
||||
'magic_constant_casing' => true,
|
||||
'native_function_casing' => true,
|
||||
'new_with_braces' => true,
|
||||
'no_blank_lines_after_class_opening' => true,
|
||||
'no_blank_lines_after_phpdoc' => true,
|
||||
'no_empty_comment' => true,
|
||||
'no_empty_phpdoc' => true,
|
||||
'no_empty_statement' => true,
|
||||
'no_extra_blank_lines' => ['tokens' => [
|
||||
'curly_brace_block',
|
||||
'extra',
|
||||
'parenthesis_brace_block',
|
||||
'square_brace_block',
|
||||
'throw',
|
||||
'use',
|
||||
]],
|
||||
'no_leading_import_slash' => true,
|
||||
'no_leading_namespace_whitespace' => true,
|
||||
'no_mixed_echo_print' => ['use' => 'echo'],
|
||||
'no_multiline_whitespace_around_double_arrow' => true,
|
||||
'no_short_bool_cast' => true,
|
||||
'no_singleline_whitespace_before_semicolons' => true,
|
||||
'no_spaces_around_offset' => true,
|
||||
'no_trailing_comma_in_list_call' => true,
|
||||
'no_trailing_comma_in_singleline_array' => true,
|
||||
'no_unneeded_curly_braces' => true,
|
||||
'no_unneeded_final_method' => true,
|
||||
'no_unused_imports' => true,
|
||||
'no_whitespace_before_comma_in_array' => true,
|
||||
'no_whitespace_in_blank_line' => true,
|
||||
'normalize_index_brace' => true,
|
||||
'object_operator_without_whitespace' => true,
|
||||
'php_unit_fqcn_annotation' => true,
|
||||
'phpdoc_align' => [
|
||||
'align' => 'left',
|
||||
'tags' => [
|
||||
'method',
|
||||
'param',
|
||||
'property',
|
||||
'return',
|
||||
'throws',
|
||||
'type',
|
||||
'var',
|
||||
],
|
||||
],
|
||||
'phpdoc_annotation_without_dot' => true,
|
||||
'phpdoc_indent' => true,
|
||||
'phpdoc_inline_tag' => true,
|
||||
'phpdoc_no_access' => true,
|
||||
'phpdoc_no_alias_tag' => true,
|
||||
'phpdoc_no_empty_return' => true,
|
||||
'phpdoc_no_package' => true,
|
||||
'phpdoc_no_useless_inheritdoc' => true,
|
||||
'phpdoc_return_self_reference' => true,
|
||||
'phpdoc_scalar' => true,
|
||||
'phpdoc_separation' => false,
|
||||
'phpdoc_single_line_var_spacing' => true,
|
||||
'phpdoc_summary' => false,
|
||||
'phpdoc_to_comment' => true,
|
||||
'phpdoc_trim' => true,
|
||||
'phpdoc_types' => true,
|
||||
'phpdoc_var_without_name' => true,
|
||||
'protected_to_private' => true,
|
||||
'return_type_declaration' => true,
|
||||
'semicolon_after_instruction' => true,
|
||||
'short_scalar_cast' => true,
|
||||
'single_blank_line_before_namespace' => true,
|
||||
'single_line_comment_style' => [
|
||||
'comment_types' => ['hash'],
|
||||
],
|
||||
'single_quote' => true,
|
||||
'space_after_semicolon' => [
|
||||
'remove_in_empty_for_expressions' => true,
|
||||
],
|
||||
'standardize_increment' => true,
|
||||
'standardize_not_equals' => true,
|
||||
'ternary_operator_spaces' => true,
|
||||
'trailing_comma_in_multiline_array' => false,
|
||||
'trim_array_spaces' => true,
|
||||
'unary_operator_spaces' => true,
|
||||
'whitespace_after_comma_in_array' => true,
|
||||
'yoda_style' => false,
|
||||
'ternary_to_null_coalescing' => true,
|
||||
'visibility_required' => ['elements' => [
|
||||
'const',
|
||||
'method',
|
||||
'property',
|
||||
]],
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->in([
|
||||
__DIR__ . '/src/',
|
||||
__DIR__ . '/tests/',
|
||||
])
|
||||
)
|
||||
->setFormat('checkstyle')
|
||||
;
|
||||
|
||||
@@ -3,44 +3,38 @@ build:
|
||||
node: v8.11.2
|
||||
nodes:
|
||||
analysis:
|
||||
project_setup:
|
||||
override:
|
||||
- 'true'
|
||||
tests:
|
||||
override:
|
||||
- php-scrutinizer-run
|
||||
-
|
||||
command: phpcs-run
|
||||
use_website_config: true
|
||||
- js-scrutinizer-run
|
||||
tests: true
|
||||
tests:
|
||||
override:
|
||||
-
|
||||
command: 'vendor/bin/phpunit --exclude-group integration --coverage-clover=unit tests/'
|
||||
coverage:
|
||||
file: 'unit'
|
||||
format: 'clover'
|
||||
-
|
||||
command: 'vendor/bin/phpunit --group integration --coverage-clover=integration tests/'
|
||||
coverage:
|
||||
file: 'integration'
|
||||
format: 'clover'
|
||||
- php-scrutinizer-run
|
||||
tests:
|
||||
tests:
|
||||
override:
|
||||
-
|
||||
command: 'vendor/bin/phpunit --exclude-group integration --coverage-clover=unit tests/'
|
||||
coverage:
|
||||
file: 'unit'
|
||||
format: 'clover'
|
||||
-
|
||||
command: 'vendor/bin/phpunit --group integration --coverage-clover=integration tests/'
|
||||
coverage:
|
||||
file: 'integration'
|
||||
format: 'clover'
|
||||
-
|
||||
command: 'bin/console kimai:phpcs --checkstyle=checkstyle'
|
||||
analysis:
|
||||
file: 'checkstyle'
|
||||
format: 'php-cs-checkstyle'
|
||||
|
||||
filter:
|
||||
excluded_paths:
|
||||
- 'tests/*'
|
||||
- 'bin/*'
|
||||
- '*/build/*'
|
||||
- 'node_modules/*'
|
||||
- 'public/*'
|
||||
- 'var/*'
|
||||
- 'vendor/*'
|
||||
checks:
|
||||
php: true
|
||||
javascript: true
|
||||
coding_style:
|
||||
php:
|
||||
spaces:
|
||||
around_operators:
|
||||
concatenation: true
|
||||
- '.github/'
|
||||
- 'bin/'
|
||||
- 'config/'
|
||||
- 'public/'
|
||||
- 'templates/'
|
||||
- 'translations/'
|
||||
- 'var/'
|
||||
dependency_paths:
|
||||
- 'node_modules/'
|
||||
- 'vendor/'
|
||||
|
||||
@@ -6,11 +6,11 @@ Send us your ideas, code reviews, pull requests and feature requests to help us
|
||||
|
||||
## Pull request rules
|
||||
|
||||
- We use PSR-2 code styles, please run `bin/console kimai:phpcs` before sending in a pull-request
|
||||
- Please add PHPUnit tests for your changes
|
||||
- Verify everything still works by executing our tests `bin/console kimai:test-unit` and `bin/console kimai:test-integration`
|
||||
- If you want to contribute new files, please add them with the file-header template from below
|
||||
- We use PSR-2 with some addons code styles (check our [php-cs-fixer config](.php_cs.dist)), run `bin/console kimai:phpcs` to verify and `bin/console kimai:phpcs --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
|
||||
- With sending in a PR, you accept that your contributions/code will be published under MIT license (see the LICENSE file as well)
|
||||
- If one of the checks fail, please fix them before asking for a review
|
||||
|
||||
### File-header template
|
||||
```
|
||||
@@ -21,3 +21,27 @@ Send us your ideas, code reviews, pull requests and feature requests to help us
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
```
|
||||
|
||||
## Translations
|
||||
|
||||
We try to keep the number of language files small to make it easier to identify the location for your new messages.
|
||||
|
||||
- If you add a new key, you have to add it in every language file
|
||||
- Its very likely that you want to edit the file `messages` as it holds 90% of our application translations
|
||||
|
||||
The files in a quick overview:
|
||||
|
||||
- `AvanzuAdminTheme` is only meant for translating strings from the original theme
|
||||
- `exceptions` only holds translations of error pages and exception handlers
|
||||
- `flashmessages`
|
||||
- `messages` holds most of the visible application translations
|
||||
- `pagerfanta` includes the translations for the pagination component
|
||||
- `sidebar` holds all the translations of the right sidebar
|
||||
- `validators` only hold translations related to violations/validation of submitted form data (or API calls)
|
||||
|
||||
## Documentation
|
||||
|
||||
The documentation is in [var/docs/](var/docs/) and its available both at GitHub and in your running Kimai instance.
|
||||
|
||||
- Please verify that all links work in your Kimai instance before submitting
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ class CreateUserCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
@@ -74,7 +74,7 @@ class CreateUserCommand extends Command
|
||||
->addArgument(
|
||||
'role',
|
||||
InputArgument::OPTIONAL,
|
||||
'A comma separated list of user roles, e.g. "'.$roles.'"',
|
||||
'A comma separated list of user roles, e.g. "' . $roles . '"',
|
||||
User::DEFAULT_ROLE
|
||||
)
|
||||
->addArgument('password', InputArgument::OPTIONAL, 'Password for the new user (requested if not provided)')
|
||||
@@ -82,7 +82,7 @@ class CreateUserCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
@@ -92,7 +92,7 @@ class CreateUserCommand extends Command
|
||||
$email = $input->getArgument('email');
|
||||
$role = $input->getArgument('role');
|
||||
|
||||
if ($input->getArgument('password') !== null) {
|
||||
if (null !== $input->getArgument('password')) {
|
||||
$password = $input->getArgument('password');
|
||||
} else {
|
||||
$password = $this->askForPassword($input, $output);
|
||||
@@ -122,6 +122,7 @@ class CreateUserCommand extends Command
|
||||
. $error->getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,10 +35,9 @@ use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
*/
|
||||
class KimaiImporterCommand extends Command
|
||||
{
|
||||
|
||||
// minimum required Kimai and database version, lower versions are not supported by this command
|
||||
const MIN_VERSION = '1.0.1';
|
||||
const MIN_REVISION = '1388';
|
||||
public const MIN_VERSION = '1.0.1';
|
||||
public const MIN_REVISION = '1388';
|
||||
|
||||
/**
|
||||
* Create the user default passwords
|
||||
@@ -110,7 +109,7 @@ class KimaiImporterCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
@@ -130,7 +129,7 @@ class KimaiImporterCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
@@ -147,12 +146,14 @@ class KimaiImporterCommand extends Command
|
||||
$password = $input->getArgument('password');
|
||||
if (trim(strlen($password)) < 6) {
|
||||
$io->error('Password length is not sufficient, at least 6 character are required');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$country = $input->getArgument('country');
|
||||
if (trim(strlen($country)) != 2) {
|
||||
if (2 != trim(strlen($country))) {
|
||||
$io->error('Country length needs to be exactly 2 character');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -174,6 +175,7 @@ class KimaiImporterCommand extends Command
|
||||
$users = $this->fetchAllFromImport('users');
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to load users: ' . $ex->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -181,6 +183,7 @@ class KimaiImporterCommand extends Command
|
||||
$customer = $this->fetchAllFromImport('customers');
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to load customers: ' . $ex->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -188,6 +191,7 @@ class KimaiImporterCommand extends Command
|
||||
$projects = $this->fetchAllFromImport('projects');
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to load projects: ' . $ex->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -195,6 +199,7 @@ class KimaiImporterCommand extends Command
|
||||
$activities = $this->fetchAllFromImport('activities');
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to load activities: ' . $ex->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -202,6 +207,7 @@ class KimaiImporterCommand extends Command
|
||||
$activityToProject = $this->fetchAllFromImport('projects_activities');
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to load activities-project mapping: ' . $ex->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -209,6 +215,7 @@ class KimaiImporterCommand extends Command
|
||||
$records = $this->fetchAllFromImport('timeSheet');
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to load timeSheet: ' . $ex->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -224,6 +231,7 @@ class KimaiImporterCommand extends Command
|
||||
$io->success('Imported users: ' . $counter);
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to import users: ' . $ex->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -233,6 +241,7 @@ class KimaiImporterCommand extends Command
|
||||
$io->success('Imported customers: ' . $counter);
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to import customers: ' . $ex->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -242,6 +251,7 @@ class KimaiImporterCommand extends Command
|
||||
$io->success('Imported projects: ' . $counter);
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to import projects: ' . $ex->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -251,6 +261,7 @@ class KimaiImporterCommand extends Command
|
||||
$io->success('Imported activities: ' . $counter);
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to import activities: ' . $ex->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -260,6 +271,7 @@ class KimaiImporterCommand extends Command
|
||||
$io->success('Imported timesheet records: ' . $counter);
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to import timesheet records: ' . $ex->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -276,7 +288,7 @@ class KimaiImporterCommand extends Command
|
||||
'Start: ' . $this->bytesHumanReadable($bytesStart) . PHP_EOL .
|
||||
'After caching: ' . $this->bytesHumanReadable($bytesCached) . PHP_EOL .
|
||||
'After import: ' . $this->bytesHumanReadable($bytesImported) . PHP_EOL .
|
||||
'Total consumption for importing '.$allImports.' new database entries: ' .
|
||||
'Total consumption for importing ' . $allImports . ' new database entries: ' .
|
||||
$this->bytesHumanReadable($bytesImported - $bytesStart)
|
||||
);
|
||||
}
|
||||
@@ -299,19 +311,21 @@ class KimaiImporterCommand extends Command
|
||||
$version = $this->getImportConnection()->query($versionQuery)->fetchColumn();
|
||||
$revision = $this->getImportConnection()->query($revisionQuery)->fetchColumn();
|
||||
|
||||
if (version_compare($requiredVersion, $version) == 1) {
|
||||
if (1 == version_compare($requiredVersion, $version)) {
|
||||
$io->error(
|
||||
'Import can only performed from an up-to-date Kimai version:' . PHP_EOL .
|
||||
'Needs at least ' . $requiredVersion . ' but found ' . $version
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (version_compare($requiredRevision, $revision) == 1) {
|
||||
if (1 == version_compare($requiredRevision, $revision)) {
|
||||
$io->error(
|
||||
'Import can only performed from an up-to-date Kimai version:' . PHP_EOL .
|
||||
'Database revision needs to be ' . $requiredRevision . ' but found ' . $revision
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -329,7 +343,7 @@ class KimaiImporterCommand extends Command
|
||||
foreach ($allListener as $name => $listener) {
|
||||
if (in_array($name, ['prePersist', 'preUpdate'])) {
|
||||
foreach ($listener as $service => $class) {
|
||||
if ($class === TimesheetSubscriber::class) {
|
||||
if (TimesheetSubscriber::class === $class) {
|
||||
$connection->getEventManager()->removeEventListener(['prePersist', 'preUpdate'], $class);
|
||||
}
|
||||
}
|
||||
@@ -345,6 +359,7 @@ class KimaiImporterCommand extends Command
|
||||
protected function bytesHumanReadable($size)
|
||||
{
|
||||
$unit = ['b', 'kB', 'MB', 'GB'];
|
||||
|
||||
return @round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $unit[$i];
|
||||
}
|
||||
|
||||
@@ -389,11 +404,12 @@ class KimaiImporterCommand extends Command
|
||||
$value = $error->getInvalidValue();
|
||||
$io->error(
|
||||
$error->getPropertyPath()
|
||||
. " (" . (is_array($value) ? implode(',', $value) : $value) .")"
|
||||
. ' (' . (is_array($value) ? implode(',', $value) : $value) . ')'
|
||||
. "\n "
|
||||
. $error->getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -435,8 +451,8 @@ class KimaiImporterCommand extends Command
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
|
||||
foreach ($users as $oldUser) {
|
||||
$isActive = (bool)$oldUser['active'] && !(bool)$oldUser['trash'] && !(bool)$oldUser['ban'];
|
||||
$role = ($oldUser['globalRoleID'] == 1) ? User::ROLE_SUPER_ADMIN : User::DEFAULT_ROLE;
|
||||
$isActive = (bool) $oldUser['active'] && !(bool) $oldUser['trash'] && !(bool) $oldUser['ban'];
|
||||
$role = (1 == $oldUser['globalRoleID']) ? User::ROLE_SUPER_ADMIN : User::DEFAULT_ROLE;
|
||||
|
||||
$user = new User();
|
||||
$user->setUsername($oldUser['name'])
|
||||
@@ -460,7 +476,7 @@ class KimaiImporterCommand extends Command
|
||||
if ($this->debug) {
|
||||
$io->success('Created user: ' . $user->getUsername());
|
||||
}
|
||||
$counter++;
|
||||
++$counter;
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to create user: ' . $user->getUsername());
|
||||
$io->error('Reason: ' . $ex->getMessage());
|
||||
@@ -468,6 +484,7 @@ class KimaiImporterCommand extends Command
|
||||
|
||||
$this->users[$oldUser['userID']] = $user;
|
||||
}
|
||||
|
||||
return $counter;
|
||||
}
|
||||
|
||||
@@ -508,7 +525,7 @@ class KimaiImporterCommand extends Command
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
|
||||
foreach ($customers as $oldCustomer) {
|
||||
$isActive = (bool)$oldCustomer['visible'] && !(bool)$oldCustomer['trash'];
|
||||
$isActive = (bool) $oldCustomer['visible'] && !(bool) $oldCustomer['trash'];
|
||||
$name = $oldCustomer['name'];
|
||||
if (empty($name)) {
|
||||
$name = uniqid();
|
||||
@@ -540,7 +557,7 @@ class KimaiImporterCommand extends Command
|
||||
if ($this->debug) {
|
||||
$io->success('Created customer: ' . $customer->getName());
|
||||
}
|
||||
$counter++;
|
||||
++$counter;
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Reason: ' . $ex->getMessage());
|
||||
$io->error('Failed to create customer: ' . $customer->getName());
|
||||
@@ -548,6 +565,7 @@ class KimaiImporterCommand extends Command
|
||||
|
||||
$this->customers[$oldCustomer['customerID']] = $customer;
|
||||
}
|
||||
|
||||
return $counter;
|
||||
}
|
||||
|
||||
@@ -577,7 +595,7 @@ class KimaiImporterCommand extends Command
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
|
||||
foreach ($projects as $oldProject) {
|
||||
$isActive = (bool)$oldProject['visible'] && !(bool)$oldProject['trash'];
|
||||
$isActive = (bool) $oldProject['visible'] && !(bool) $oldProject['trash'];
|
||||
$customer = $this->customers[$oldProject['customerID']];
|
||||
$name = $oldProject['name'];
|
||||
if (empty($name)) {
|
||||
@@ -603,7 +621,7 @@ class KimaiImporterCommand extends Command
|
||||
if ($this->debug) {
|
||||
$io->success('Created project: ' . $project->getName() . ' for customer: ' . $customer->getName());
|
||||
}
|
||||
$counter++;
|
||||
++$counter;
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to create project: ' . $project->getName());
|
||||
$io->error('Reason: ' . $ex->getMessage());
|
||||
@@ -611,6 +629,7 @@ class KimaiImporterCommand extends Command
|
||||
|
||||
$this->projects[$oldProject['projectID']] = $project;
|
||||
}
|
||||
|
||||
return $counter;
|
||||
}
|
||||
|
||||
@@ -662,11 +681,12 @@ class KimaiImporterCommand extends Command
|
||||
|
||||
$this->unassignedActivities[$oldActivity['activityID']] = $oldActivity;
|
||||
$this->createActivity($io, $entityManager, $project, $oldActivity);
|
||||
$counter++;
|
||||
++$counter;
|
||||
} else {
|
||||
$this->unassignedActivities[$oldActivity['activityID']] = $oldActivity;
|
||||
}
|
||||
}
|
||||
|
||||
return $counter;
|
||||
}
|
||||
|
||||
@@ -689,7 +709,7 @@ class KimaiImporterCommand extends Command
|
||||
return $this->activities[$activityId][$project->getId()];
|
||||
}
|
||||
|
||||
$isActive = (bool)$oldActivity['visible'] && !(bool)$oldActivity['trash'];
|
||||
$isActive = (bool) $oldActivity['visible'] && !(bool) $oldActivity['trash'];
|
||||
$name = $oldActivity['name'];
|
||||
if (empty($name)) {
|
||||
$name = uniqid();
|
||||
@@ -778,13 +798,13 @@ class KimaiImporterCommand extends Command
|
||||
$activity = $this->activities[$activityId][$projectId];
|
||||
}
|
||||
|
||||
if ($activity === null && isset($this->unassignedActivities[$activityId])) {
|
||||
if (null === $activity && isset($this->unassignedActivities[$activityId])) {
|
||||
$oldActivity = $this->unassignedActivities[$activityId];
|
||||
$activity = $this->createActivity($io, $entityManager, $project, $oldActivity);
|
||||
$activityCounter++;
|
||||
++$activityCounter;
|
||||
}
|
||||
|
||||
if ($activity === null) {
|
||||
if (null === $activity) {
|
||||
$io->error('Could not create timesheet record, missing activity with ID: ' . $activityId);
|
||||
continue;
|
||||
}
|
||||
@@ -792,7 +812,7 @@ class KimaiImporterCommand extends Command
|
||||
$duration = $oldRecord['end'] - $oldRecord['start'];
|
||||
|
||||
$rate = $oldRecord['fixedRate'];
|
||||
if ((empty($rate) || $rate == 0.00) && !empty($oldRecord['rate'])) {
|
||||
if ((empty($rate) || 0.00 == $rate) && !empty($oldRecord['rate'])) {
|
||||
$hourlyRate = (float) $oldRecord['rate'];
|
||||
$rate = (float) $hourlyRate * ($duration / 3600);
|
||||
$rate = round($rate, 2);
|
||||
@@ -802,8 +822,8 @@ class KimaiImporterCommand extends Command
|
||||
$timesheet
|
||||
->setDescription($oldRecord['description'] ?: ($oldRecord['comment'] ?: null))
|
||||
->setUser($this->users[$oldRecord['userID']])
|
||||
->setBegin(new \DateTime("@".$oldRecord['start']))
|
||||
->setEnd(new \DateTime("@".$oldRecord['end']))
|
||||
->setBegin(new \DateTime('@' . $oldRecord['start']))
|
||||
->setEnd(new \DateTime('@' . $oldRecord['end']))
|
||||
->setDuration($duration)
|
||||
->setActivity($activity)
|
||||
->setRate($rate)
|
||||
@@ -819,13 +839,13 @@ class KimaiImporterCommand extends Command
|
||||
if ($this->debug) {
|
||||
$io->success('Created timesheet record: ' . $timesheet->getId());
|
||||
}
|
||||
$counter++;
|
||||
++$counter;
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to create timesheet record: ' . $timesheet->getId());
|
||||
$io->error('Reason: ' . $ex->getMessage());
|
||||
}
|
||||
|
||||
if ($counter % 500 == 0) {
|
||||
if (0 == $counter % 500) {
|
||||
$io->writeln('Imported ' . $counter . ' timesheet records, import ongoing ...');
|
||||
}
|
||||
}
|
||||
@@ -833,6 +853,7 @@ class KimaiImporterCommand extends Command
|
||||
if ($activityCounter > 0) {
|
||||
$io->success('Created new (previously unattached) activities during timesheet import: ' . $activityCounter);
|
||||
}
|
||||
|
||||
return $counter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,8 @@ use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
*/
|
||||
class ResetCommand extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
@@ -56,6 +55,7 @@ EOT
|
||||
$command->run(new ArrayInput([]), $output);
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to create database: ' . $ex->getMessage());
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,7 @@ EOT
|
||||
$command->run(new ArrayInput(['--force' => true]), $output);
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to drop database schema: ' . $ex->getMessage());
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -74,6 +75,7 @@ EOT
|
||||
$command->run(new ArrayInput([]), $output);
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to create database schema: ' . $ex->getMessage());
|
||||
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
@@ -85,6 +87,7 @@ EOT
|
||||
$command->run($cmdInput, $output);
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to import fixtures: ' . $ex->getMessage());
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
@@ -94,6 +97,7 @@ EOT
|
||||
$command->run(new ArrayInput([]), $output);
|
||||
} catch (\Exception $ex) {
|
||||
$io->error('Failed to clear cache: ' . $ex->getMessage());
|
||||
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
@@ -101,7 +105,6 @@ EOT
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
|
||||
@@ -11,22 +11,22 @@ namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
/**
|
||||
* Command used to check the project coding styles.
|
||||
* Command used to check and apply the projects coding styles.
|
||||
*/
|
||||
class RunCodeSnifferCommand extends Command
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $rootDir;
|
||||
protected $rootDir = '';
|
||||
|
||||
/**
|
||||
* RunCodeSnifferCommand constructor.
|
||||
* @param $projectDirectory
|
||||
* @param string $projectDirectory
|
||||
*/
|
||||
public function __construct($projectDirectory)
|
||||
{
|
||||
@@ -35,46 +35,64 @@ class RunCodeSnifferCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('kimai:phpcs')
|
||||
->setDescription('Run PHP_CodeSniffer to check for the projects coding style')
|
||||
->addOption('fix', null, InputOption::VALUE_NONE, 'Fix all found problems (risky: modifies your files)')
|
||||
->addOption('checkstyle', null, InputOption::VALUE_OPTIONAL, '')
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
|
||||
$this->executeCodeSniffer($io, '/src');
|
||||
$this->executeCodeSniffer($io, '/tests');
|
||||
$this->executeCodeSniffer($io, '/templates');
|
||||
}
|
||||
$filename = null;
|
||||
ob_start();
|
||||
|
||||
/**
|
||||
* @param string $directory
|
||||
*/
|
||||
protected function executeCodeSniffer(SymfonyStyle $io, $directory)
|
||||
{
|
||||
$directory = $this->rootDir . $directory;
|
||||
$args = [];
|
||||
if (!$input->getOption('fix')) {
|
||||
$filename = $input->getOption('checkstyle');
|
||||
$args[] = '--dry-run';
|
||||
$args[] = '--verbose';
|
||||
$args[] = '--show-progress=none';
|
||||
|
||||
if (!empty($filename) && (file_exists($filename) && !is_writeable($filename))) {
|
||||
$io->error('Target file is not writeable: ' . $filename);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!empty($filename)) {
|
||||
$filename = $this->rootDir . '/' . $filename;
|
||||
$args[] = '> ' . $filename;
|
||||
} else {
|
||||
$args[] = '--format=txt';
|
||||
}
|
||||
}
|
||||
|
||||
$exitCode = 0;
|
||||
ob_start();
|
||||
passthru($this->rootDir . '/bin/phpcs --standard=PSR2 ' . $directory, $exitCode);
|
||||
passthru($this->rootDir . '/vendor/bin/php-cs-fixer fix ' . implode(' ', $args), $exitCode);
|
||||
$result = ob_get_clean();
|
||||
|
||||
$io->write($result);
|
||||
|
||||
if ($exitCode > 0) {
|
||||
$io->error('Found problems while checking sources at: ' . $directory);
|
||||
} else {
|
||||
$io->success('All sources look good at: ' . $directory);
|
||||
$io->error(
|
||||
'Found problems while checking your code styles' .
|
||||
(!empty($filename) ? '. Saved checkstyle data to: ' . $filename : '')
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$io->success('All source files have proper code styles');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
/**
|
||||
* Command used to run all integration tests.
|
||||
@@ -20,7 +17,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
class RunIntegrationTestsCommand extends RunUnitTestsCommand
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
|
||||
@@ -19,7 +19,6 @@ use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
*/
|
||||
class RunUnitTestsCommand extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
@@ -36,7 +35,7 @@ class RunUnitTestsCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
@@ -48,7 +47,7 @@ class RunUnitTestsCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
|
||||
@@ -17,9 +17,9 @@ class Constants
|
||||
/**
|
||||
* Currently only used for informational purpose in the footer
|
||||
*/
|
||||
const VERSION = '2.0 dev';
|
||||
public const VERSION = '2.0 dev';
|
||||
/**
|
||||
* Used in multiple views
|
||||
*/
|
||||
const GITHUB = 'https://github.com/kevinpapst/kimai2/';
|
||||
public const GITHUB = 'https://github.com/kevinpapst/kimai2/';
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
*/
|
||||
abstract class AbstractController extends Controller
|
||||
{
|
||||
const FLASH_SUCCESS = 'success';
|
||||
const FLASH_WARNING = 'warning';
|
||||
const FLASH_ERROR = 'error';
|
||||
public const FLASH_SUCCESS = 'success';
|
||||
public const FLASH_WARNING = 'warning';
|
||||
public const FLASH_ERROR = 'error';
|
||||
|
||||
const DOMAIN_FLASH = 'flashmessages';
|
||||
const DOMAIN_ERROR = 'exceptions';
|
||||
public const DOMAIN_FLASH = 'flashmessages';
|
||||
public const DOMAIN_ERROR = 'exceptions';
|
||||
|
||||
const ROLE_ADMIN = 'ROLE_ADMIN';
|
||||
public const ROLE_ADMIN = 'ROLE_ADMIN';
|
||||
|
||||
/**
|
||||
* @return object|\Symfony\Component\Translation\DataCollectorTranslator|\Symfony\Component\Translation\IdentityTranslator
|
||||
@@ -37,8 +37,8 @@ abstract class AbstractController extends Controller
|
||||
/**
|
||||
* A translated helper for denyAccessUnlessGranted()
|
||||
*
|
||||
* @param $attributes
|
||||
* @param null $subject
|
||||
* @param mixed $attributes
|
||||
* @param mixed $subject
|
||||
* @param string $translation
|
||||
* @param array $parameter
|
||||
* @throws AccessDeniedException
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use App\Entity\Activity;
|
||||
use App\Repository\ActivityRepository;
|
||||
@@ -22,7 +21,6 @@ use App\Repository\ActivityRepository;
|
||||
*/
|
||||
class ActivityController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @return ActivityRepository
|
||||
*/
|
||||
|
||||
@@ -30,7 +30,6 @@ use App\Repository\Query\ActivityQuery;
|
||||
*/
|
||||
class ActivityController extends AbstractController
|
||||
{
|
||||
|
||||
/**
|
||||
* @return \App\Repository\ActivityRepository
|
||||
*/
|
||||
@@ -116,7 +115,7 @@ class ActivityController extends AbstractController
|
||||
|
||||
$deleteForm->handleRequest($request);
|
||||
|
||||
if ($stats->getRecordAmount() == 0 || ($deleteForm->isSubmitted() && $deleteForm->isValid())) {
|
||||
if (0 == $stats->getRecordAmount() || ($deleteForm->isSubmitted() && $deleteForm->isValid())) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->remove($activity);
|
||||
$entityManager->flush();
|
||||
|
||||
@@ -29,7 +29,6 @@ use App\Repository\Query\CustomerQuery;
|
||||
*/
|
||||
class CustomerController extends AbstractController
|
||||
{
|
||||
|
||||
/**
|
||||
* @return \App\Repository\CustomerRepository
|
||||
*/
|
||||
@@ -133,7 +132,7 @@ class CustomerController extends AbstractController
|
||||
|
||||
$deleteForm->handleRequest($request);
|
||||
|
||||
if ($stats->getRecordAmount() == 0 || ($deleteForm->isSubmitted() && $deleteForm->isValid())) {
|
||||
if (0 == $stats->getRecordAmount() || ($deleteForm->isSubmitted() && $deleteForm->isValid())) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->remove($customer);
|
||||
$entityManager->flush();
|
||||
|
||||
@@ -31,7 +31,6 @@ use App\Repository\Query\ProjectQuery;
|
||||
*/
|
||||
class ProjectController extends AbstractController
|
||||
{
|
||||
|
||||
/**
|
||||
* @return \App\Repository\ProjectRepository
|
||||
*/
|
||||
@@ -110,7 +109,7 @@ class ProjectController extends AbstractController
|
||||
|
||||
$deleteForm->handleRequest($request);
|
||||
|
||||
if ($stats->getRecordAmount() == 0 || ($deleteForm->isSubmitted() && $deleteForm->isValid())) {
|
||||
if (0 == $stats->getRecordAmount() || ($deleteForm->isSubmitted() && $deleteForm->isValid())) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->remove($project);
|
||||
$entityManager->flush();
|
||||
|
||||
@@ -133,9 +133,15 @@ class TimesheetController extends AbstractController
|
||||
*/
|
||||
public function deleteAction(Timesheet $entry, Request $request)
|
||||
{
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->remove($entry);
|
||||
$entityManager->flush();
|
||||
try {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->remove($entry);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->flashSuccess('action.deleted_successfully');
|
||||
} catch (\Exception $ex) {
|
||||
$this->flashError('action.deleted.error', ['%reason%' => $ex->getMessage()]);
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('admin_timesheet_paginated', ['page' => $request->get('page')]);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
*/
|
||||
class UserController extends AbstractController
|
||||
{
|
||||
|
||||
/**
|
||||
* @Route("/", defaults={"page": 1}, name="admin_user")
|
||||
* @Route("/page/{page}", requirements={"page": "[1-9]\d*"}, name="admin_user_paginated")
|
||||
|
||||
@@ -105,7 +105,7 @@ class DashboardController extends Controller
|
||||
//"{{ widgets.info_box_counter('stats.amountThisMonth', timesheetGlobal.amountThisMonth|money, 'money', 'green') }}",
|
||||
"{{ widgets.info_box_counter('stats.durationTotal', timesheetGlobal.durationTotal|duration(true), 'hourglass-o', 'yellow') }}",
|
||||
//"{{ widgets.info_box_counter('stats.amountTotal', timesheetGlobal.amountTotal|money, 'money', 'red') }}",
|
||||
"{{ widgets.info_box_counter('stats.activeRecordings', timesheetGlobal.activeCurrently, 'hourglass-o', 'red', path('admin_timesheet', {'state': ".TimesheetQuery::STATE_RUNNING."})) }}",
|
||||
"{{ widgets.info_box_counter('stats.activeRecordings', timesheetGlobal.activeCurrently, 'hourglass-o', 'red', path('admin_timesheet', {'state': " . TimesheetQuery::STATE_RUNNING . '})) }}',
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
@@ -23,9 +23,8 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
*/
|
||||
class HelpController extends Controller
|
||||
{
|
||||
|
||||
const README = 'README';
|
||||
const DOCS_DIR = 'var/docs/';
|
||||
public const README = 'README';
|
||||
public const DOCS_DIR = 'var/docs/';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
@@ -49,10 +48,10 @@ class HelpController extends Controller
|
||||
* @param string $chapter
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function indexAction(?string $chapter)
|
||||
public function indexAction(string $chapter)
|
||||
{
|
||||
$breadcrumb = [self::README];
|
||||
if ($chapter !== self::README) {
|
||||
if (self::README !== $chapter) {
|
||||
$breadcrumb[] = $chapter;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ use App\Model\InvoiceModel;
|
||||
use App\Repository\Query\BaseQuery;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
use App\Repository\Query\TimesheetQuery;
|
||||
use App\Repository\TimesheetRepository;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
@@ -31,7 +32,6 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
*/
|
||||
class InvoiceController extends AbstractController
|
||||
{
|
||||
|
||||
/**
|
||||
* @var ServiceInvoice
|
||||
*/
|
||||
@@ -97,11 +97,13 @@ class InvoiceController extends AbstractController
|
||||
$query = $form->getData();
|
||||
$query->setResultType(TimesheetQuery::RESULT_TYPE_QUERYBUILDER);
|
||||
|
||||
if ($query->getCustomer() !== null) {
|
||||
if (null !== $query->getCustomer()) {
|
||||
$query->getBegin()->setTime(0, 0, 0);
|
||||
$query->getEnd()->setTime(23, 59, 59);
|
||||
|
||||
$queryBuilder = $this->getDoctrine()->getRepository(Timesheet::class)->findByQuery($query);
|
||||
/* @var TimesheetRepository $timeRepo */
|
||||
$timeRepo = $this->getDoctrine()->getRepository(Timesheet::class);
|
||||
$queryBuilder = $timeRepo->findByQuery($query);
|
||||
$entries = $queryBuilder->getQuery()->getResult();
|
||||
}
|
||||
}
|
||||
@@ -114,12 +116,12 @@ class InvoiceController extends AbstractController
|
||||
$action = null;
|
||||
if ($query->getTemplate() !== null) {
|
||||
$generator = $this->service->getNumberGeneratorByName($query->getTemplate()->getNumberGenerator());
|
||||
if ($generator === null) {
|
||||
if (null === $generator) {
|
||||
throw new \Exception('Unknown number generator: ' . $query->getTemplate()->getNumberGenerator());
|
||||
}
|
||||
|
||||
$calculator = $this->service->getCalculatorByName($query->getTemplate()->getCalculator());
|
||||
if ($calculator === null) {
|
||||
if (null === $calculator) {
|
||||
throw new \Exception('Unknown invoice calculator: ' . $query->getTemplate()->getCalculator());
|
||||
}
|
||||
|
||||
@@ -144,12 +146,12 @@ class InvoiceController extends AbstractController
|
||||
* TODO permission
|
||||
*
|
||||
* @param $page
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function listTemplateAction($page, Request $request)
|
||||
public function listTemplateAction($page)
|
||||
{
|
||||
$templates = $this->getRepository()->findByQuery(new BaseQuery());
|
||||
|
||||
return $this->render('invoice/templates.html.twig', [
|
||||
'entries' => $templates,
|
||||
'page' => $page,
|
||||
@@ -186,6 +188,7 @@ class InvoiceController extends AbstractController
|
||||
if (!$this->getRepository()->hasTemplate()) {
|
||||
$this->flashWarning('invoice.first_template');
|
||||
}
|
||||
|
||||
return $this->renderTemplateForm(new InvoiceTemplate(), $request);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as SymfonyAbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||
@@ -18,7 +18,7 @@ use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||
* Controller used to manage the application security.
|
||||
* See http://symfony.com/doc/current/cookbook/security/form_login_setup.html.
|
||||
*/
|
||||
class SecurityController extends AbstractController
|
||||
class SecurityController extends SymfonyAbstractController
|
||||
{
|
||||
/**
|
||||
* @Route("/login", name="security_login")
|
||||
@@ -30,6 +30,7 @@ class SecurityController extends AbstractController
|
||||
'error' => $helper->getLastAuthenticationError(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the route the user can use to logout.
|
||||
*
|
||||
|
||||
@@ -95,10 +95,9 @@ class TimesheetController extends AbstractController
|
||||
* @Security("is_granted('stop', entry)")
|
||||
*
|
||||
* @param Timesheet $entry
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function stopAction(Timesheet $entry, Request $request)
|
||||
public function stopAction(Timesheet $entry)
|
||||
{
|
||||
return $this->stop($entry, 'timesheet');
|
||||
}
|
||||
@@ -110,10 +109,9 @@ class TimesheetController extends AbstractController
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('start', activity)")
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function startAction(Activity $activity, Request $request)
|
||||
public function startAction(Activity $activity)
|
||||
{
|
||||
$user = $this->getUser();
|
||||
|
||||
@@ -170,9 +168,15 @@ class TimesheetController extends AbstractController
|
||||
*/
|
||||
public function deleteAction(Timesheet $entry, Request $request)
|
||||
{
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->remove($entry);
|
||||
$entityManager->flush();
|
||||
try {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->remove($entry);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->flashSuccess('action.deleted_successfully');
|
||||
} catch (\Exception $ex) {
|
||||
$this->flashError('action.deleted.error', ['%reason%' => $ex->getMessage()]);
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('timesheet_paginated', ['page' => $request->get('page')]);
|
||||
}
|
||||
|
||||
@@ -10,15 +10,17 @@
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\Timesheet;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use App\Repository\TimesheetRepository;
|
||||
use Doctrine\Common\Persistence\ManagerRegistry;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Helper functions for Timesheet controller
|
||||
*/
|
||||
trait TimesheetControllerTrait
|
||||
{
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
@@ -164,4 +166,45 @@ trait TimesheetControllerTrait
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
abstract protected function getEditForm(Timesheet $entry, $page);
|
||||
|
||||
/**
|
||||
* Adds a "successful" flash message to the stack.
|
||||
*
|
||||
* @param string $translationKey
|
||||
* @param array $parameter
|
||||
*/
|
||||
abstract protected function flashSuccess($translationKey, $parameter = []);
|
||||
|
||||
/**
|
||||
* Adds a "error" flash message to the stack.
|
||||
*
|
||||
* @param $translationKey
|
||||
* @param array $parameter
|
||||
*/
|
||||
abstract protected function flashError($translationKey, $parameter = []);
|
||||
|
||||
/**
|
||||
* Shortcut to return the Doctrine Registry service.
|
||||
*
|
||||
* @throws \LogicException If DoctrineBundle is not available
|
||||
*/
|
||||
abstract protected function getDoctrine(): ManagerRegistry;
|
||||
|
||||
/**
|
||||
* Returns a RedirectResponse to the given route with the given parameters.
|
||||
*/
|
||||
abstract protected function redirectToRoute(string $route, array $parameters = [], int $status = 302): RedirectResponse;
|
||||
|
||||
/**
|
||||
* Renders a view.
|
||||
*/
|
||||
abstract protected function render(string $view, array $parameters = [], Response $response = null): Response;
|
||||
|
||||
/**
|
||||
* Get a user from the Security Token Storage.
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \LogicException If SecurityBundle is not available
|
||||
*/
|
||||
abstract protected function getUser();
|
||||
}
|
||||
|
||||
@@ -26,11 +26,11 @@ class AppFixtures extends Fixture
|
||||
{
|
||||
use FixturesTrait;
|
||||
|
||||
const DEFAULT_PASSWORD = 'kitten';
|
||||
const USERNAME_USER = 'john_user';
|
||||
const USERNAME_TEAMLEAD = 'tony_teamlead';
|
||||
const USERNAME_ADMIN = 'anna_admin';
|
||||
const USERNAME_SUPER_ADMIN = 'susan_super';
|
||||
public const DEFAULT_PASSWORD = 'kitten';
|
||||
public const USERNAME_USER = 'john_user';
|
||||
public const USERNAME_TEAMLEAD = 'tony_teamlead';
|
||||
public const USERNAME_ADMIN = 'anna_admin';
|
||||
public const USERNAME_SUPER_ADMIN = 'susan_super';
|
||||
|
||||
/**
|
||||
* @var UserPasswordEncoderInterface
|
||||
@@ -87,7 +87,7 @@ class AppFixtures extends Fixture
|
||||
}
|
||||
|
||||
/**
|
||||
* @return []
|
||||
* @return array
|
||||
*/
|
||||
protected function getUserDefinition()
|
||||
{
|
||||
|
||||
@@ -44,6 +44,7 @@ trait FixturesTrait
|
||||
protected function getRandomPhrase()
|
||||
{
|
||||
$phrases = $this->getPhrases();
|
||||
|
||||
return $phrases[array_rand($phrases)];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ use Doctrine\Common\Persistence\ObjectManager;
|
||||
*/
|
||||
class InvoiceFixtures extends Fixture
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -28,9 +28,9 @@ class TimesheetFixtures extends Fixture
|
||||
{
|
||||
use FixturesTrait;
|
||||
|
||||
const AMOUNT_TIMESHEET = 5000; // timesheet entries total
|
||||
const RATE_MIN = 10; // minimum rate for one hour
|
||||
const RATE_MAX = 80; // maximum rate for one hour
|
||||
public const AMOUNT_TIMESHEET = 5000; // timesheet entries total
|
||||
public const RATE_MIN = 10; // minimum rate for one hour
|
||||
public const RATE_MAX = 80; // maximum rate for one hour
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -55,6 +55,7 @@ class TimesheetFixtures extends Fixture
|
||||
foreach ($entries as $temp) {
|
||||
$all[$temp->getId()] = $temp;
|
||||
}
|
||||
|
||||
return $all;
|
||||
}
|
||||
|
||||
@@ -70,6 +71,7 @@ class TimesheetFixtures extends Fixture
|
||||
foreach ($entries as $temp) {
|
||||
$all[$temp->getId()] = $temp;
|
||||
}
|
||||
|
||||
return $all;
|
||||
}
|
||||
|
||||
@@ -85,8 +87,10 @@ class TimesheetFixtures extends Fixture
|
||||
foreach ($entries as $temp) {
|
||||
$all[$temp->getId()] = $temp;
|
||||
}
|
||||
|
||||
return $all;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ObjectManager $manager
|
||||
* @return Activity[]
|
||||
@@ -99,6 +103,7 @@ class TimesheetFixtures extends Fixture
|
||||
foreach ($entries as $temp) {
|
||||
$all[$temp->getId()] = $temp;
|
||||
}
|
||||
|
||||
return $all;
|
||||
}
|
||||
|
||||
@@ -181,7 +186,7 @@ class TimesheetFixtures extends Fixture
|
||||
$i = 1;
|
||||
|
||||
foreach ($allCustomer as $customerName) {
|
||||
$visible = $i++ % 6 != 0;
|
||||
$visible = 0 != $i++ % 6;
|
||||
$entry = new Customer();
|
||||
$entry
|
||||
->setCurrency($this->getRandomCurrency())
|
||||
@@ -205,7 +210,7 @@ class TimesheetFixtures extends Fixture
|
||||
foreach ($allCustomer as $id => $customer) {
|
||||
$projectForCustomer = rand(0, 7);
|
||||
for ($i = 1; $i <= $projectForCustomer; $i++) {
|
||||
$visible = $i % 5 != 0;
|
||||
$visible = 0 != $i % 5;
|
||||
$entry = new Project();
|
||||
|
||||
$entry
|
||||
@@ -228,7 +233,7 @@ class TimesheetFixtures extends Fixture
|
||||
foreach ($allProject as $projectId => $project) {
|
||||
$activityCount = rand(0, 10);
|
||||
for ($i = 1; $i <= $activityCount; $i++) {
|
||||
$visible = $i % 4 != 0;
|
||||
$visible = 0 != $i % 4;
|
||||
$entry = new Activity();
|
||||
$entry
|
||||
->setName($this->getRandomActivity() . ($visible ? '' : '.'))
|
||||
@@ -283,6 +288,7 @@ class TimesheetFixtures extends Fixture
|
||||
private function getRandomActivity()
|
||||
{
|
||||
$all = $this->getActivities();
|
||||
|
||||
return $all[array_rand($all)];
|
||||
}
|
||||
|
||||
@@ -321,6 +327,7 @@ class TimesheetFixtures extends Fixture
|
||||
private function getRandomProject()
|
||||
{
|
||||
$all = $this->getProjects();
|
||||
|
||||
return $all[array_rand($all)];
|
||||
}
|
||||
|
||||
@@ -361,6 +368,7 @@ class TimesheetFixtures extends Fixture
|
||||
private function getRandomLocation()
|
||||
{
|
||||
$all = $this->getLocations();
|
||||
|
||||
return $all[array_rand($all)];
|
||||
}
|
||||
|
||||
@@ -430,6 +438,7 @@ class TimesheetFixtures extends Fixture
|
||||
private function getRandomCurrency()
|
||||
{
|
||||
$all = $this->getCurrencies();
|
||||
|
||||
return $all[array_rand($all)];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ use Symfony\Component\Yaml\Yaml;
|
||||
*/
|
||||
class DoctrineCompilerPass implements CompilerPassInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
@@ -47,16 +46,16 @@ class DoctrineCompilerPass implements CompilerPassInterface
|
||||
}
|
||||
*/
|
||||
|
||||
if ($engine === null) {
|
||||
if (null === $engine) {
|
||||
$dbConfig = explode('://', getenv('DATABASE_URL'));
|
||||
$engine = $dbConfig['0'] ?: null;
|
||||
}
|
||||
|
||||
if ($engine === null) {
|
||||
if (null === $engine) {
|
||||
$engine = getenv('DATABASE_ENGINE');
|
||||
}
|
||||
|
||||
if ($engine === null) {
|
||||
if (null === $engine) {
|
||||
throw new \Exception(
|
||||
'Could not detect database engine. Please set the environment config DATABASE_ENGINE ' .
|
||||
'to one of: "' . implode(', ', $this->allowedEngines) . '" in your .env file: DATABASE_ENGINE=sqlite'
|
||||
|
||||
@@ -40,7 +40,7 @@ class TablePrefixSubscriber implements EventSubscriber
|
||||
$classMetadata->setPrimaryTable(['name' => $this->prefix . $classMetadata->getTableName()]);
|
||||
|
||||
foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
|
||||
if ($mapping['type'] == \Doctrine\ORM\Mapping\ClassMetadataInfo::MANY_TO_MANY
|
||||
if (\Doctrine\ORM\Mapping\ClassMetadataInfo::MANY_TO_MANY == $mapping['type']
|
||||
// Check if "joinTable" exists:
|
||||
// it can be null if this field is the reverse side of a ManyToMany relationship
|
||||
&& array_key_exists('name', $classMetadata->associationMappings[$fieldName]['joinTable'])) {
|
||||
|
||||
@@ -20,9 +20,8 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||
*/
|
||||
class Activity
|
||||
{
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
* @var int
|
||||
*
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
* @ORM\Id
|
||||
@@ -56,7 +55,7 @@ class Activity
|
||||
private $comment;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
* @var bool
|
||||
*
|
||||
* @ORM\Column(name="visible", type="boolean", nullable=false)
|
||||
* @Assert\NotNull()
|
||||
@@ -85,6 +84,7 @@ class Activity
|
||||
public function setProject($project)
|
||||
{
|
||||
$this->project = $project;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ class Activity
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -119,6 +120,7 @@ class Activity
|
||||
public function setComment($comment)
|
||||
{
|
||||
$this->comment = $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -135,20 +137,21 @@ class Activity
|
||||
/**
|
||||
* Set visible
|
||||
*
|
||||
* @param boolean $visible
|
||||
* @param bool $visible
|
||||
*
|
||||
* @return Activity
|
||||
*/
|
||||
public function setVisible($visible)
|
||||
{
|
||||
$this->visible = $visible;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get visible
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function getVisible()
|
||||
{
|
||||
@@ -158,7 +161,7 @@ class Activity
|
||||
/**
|
||||
* Get activity id
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
|
||||
@@ -20,11 +20,10 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||
*/
|
||||
class Customer
|
||||
{
|
||||
|
||||
const DEFAULT_CURRENCY = 'EUR';
|
||||
public const DEFAULT_CURRENCY = 'EUR';
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
* @var int
|
||||
*
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
* @ORM\Id
|
||||
@@ -63,7 +62,7 @@ class Customer
|
||||
private $projects;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
* @var bool
|
||||
*
|
||||
* @ORM\Column(name="visible", type="boolean", nullable=false)
|
||||
* @Assert\NotNull()
|
||||
@@ -167,6 +166,7 @@ class Customer
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -187,6 +187,7 @@ class Customer
|
||||
public function setNumber(string $number)
|
||||
{
|
||||
$this->number = $number;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -207,6 +208,7 @@ class Customer
|
||||
public function setComment($comment)
|
||||
{
|
||||
$this->comment = $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -223,19 +225,20 @@ class Customer
|
||||
/**
|
||||
* Set visible
|
||||
*
|
||||
* @param boolean $visible
|
||||
* @param bool $visible
|
||||
* @return Customer
|
||||
*/
|
||||
public function setVisible($visible)
|
||||
{
|
||||
$this->visible = $visible;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get visible
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function getVisible()
|
||||
{
|
||||
@@ -251,6 +254,7 @@ class Customer
|
||||
public function setCompany($company)
|
||||
{
|
||||
$this->company = $company;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -273,6 +277,7 @@ class Customer
|
||||
public function setContact($contact)
|
||||
{
|
||||
$this->contact = $contact;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -293,6 +298,7 @@ class Customer
|
||||
public function setAddress($address)
|
||||
{
|
||||
$this->address = $address;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -313,6 +319,7 @@ class Customer
|
||||
public function setCountry($country)
|
||||
{
|
||||
$this->country = $country;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -333,6 +340,7 @@ class Customer
|
||||
public function setCurrency($currency)
|
||||
{
|
||||
$this->currency = $currency;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -353,6 +361,7 @@ class Customer
|
||||
public function setPhone($phone)
|
||||
{
|
||||
$this->phone = $phone;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -375,6 +384,7 @@ class Customer
|
||||
public function setFax($fax)
|
||||
{
|
||||
$this->fax = $fax;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -397,6 +407,7 @@ class Customer
|
||||
public function setMobile($mobile)
|
||||
{
|
||||
$this->mobile = $mobile;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -419,6 +430,7 @@ class Customer
|
||||
public function setMail($mail)
|
||||
{
|
||||
$this->mail = $mail;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -441,6 +453,7 @@ class Customer
|
||||
public function setHomepage($homepage)
|
||||
{
|
||||
$this->homepage = $homepage;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -463,6 +476,7 @@ class Customer
|
||||
public function setTimezone($timezone)
|
||||
{
|
||||
$this->timezone = $timezone;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -483,6 +497,7 @@ class Customer
|
||||
public function setProjects($projects)
|
||||
{
|
||||
$this->projects = $projects;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||
class InvoiceTemplate
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
* @var int
|
||||
*
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
* @ORM\Id
|
||||
@@ -128,6 +128,7 @@ class InvoiceTemplate
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -156,6 +157,7 @@ class InvoiceTemplate
|
||||
public function setTitle(string $title)
|
||||
{
|
||||
$this->title = $title;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -174,6 +176,7 @@ class InvoiceTemplate
|
||||
public function setAddress($address)
|
||||
{
|
||||
$this->address = $address;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -192,6 +195,7 @@ class InvoiceTemplate
|
||||
public function setNumberGenerator(string $numberGenerator)
|
||||
{
|
||||
$this->numberGenerator = $numberGenerator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -210,6 +214,7 @@ class InvoiceTemplate
|
||||
public function setDueDays(int $dueDays)
|
||||
{
|
||||
$this->dueDays = $dueDays;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -228,6 +233,7 @@ class InvoiceTemplate
|
||||
public function setVat(float $vat)
|
||||
{
|
||||
$this->vat = $vat;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -246,6 +252,7 @@ class InvoiceTemplate
|
||||
public function setCompany(string $company)
|
||||
{
|
||||
$this->company = $company;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -264,6 +271,7 @@ class InvoiceTemplate
|
||||
public function setRenderer(string $renderer)
|
||||
{
|
||||
$this->renderer = $renderer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -282,6 +290,7 @@ class InvoiceTemplate
|
||||
public function setCalculator(string $calculator)
|
||||
{
|
||||
$this->calculator = $calculator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -300,6 +309,7 @@ class InvoiceTemplate
|
||||
public function setPaymentTerms(string $paymentTerms)
|
||||
{
|
||||
$this->paymentTerms = $paymentTerms;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,8 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||
*/
|
||||
class Project
|
||||
{
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
* @var int
|
||||
*
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
* @ORM\Id
|
||||
@@ -64,7 +63,7 @@ class Project
|
||||
private $comment;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
* @var bool
|
||||
*
|
||||
* @ORM\Column(name="visible", type="boolean", nullable=false)
|
||||
* @Assert\NotNull()
|
||||
@@ -89,7 +88,7 @@ class Project
|
||||
/**
|
||||
* Get projectid
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
@@ -111,6 +110,7 @@ class Project
|
||||
public function setCustomer($customer)
|
||||
{
|
||||
$this->customer = $customer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ class Project
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -145,6 +146,7 @@ class Project
|
||||
public function setComment($comment)
|
||||
{
|
||||
$this->comment = $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -161,19 +163,20 @@ class Project
|
||||
/**
|
||||
* Set visible
|
||||
*
|
||||
* @param boolean $visible
|
||||
* @param bool $visible
|
||||
* @return Project
|
||||
*/
|
||||
public function setVisible($visible)
|
||||
{
|
||||
$this->visible = $visible;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get visible
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function getVisible()
|
||||
{
|
||||
@@ -189,6 +192,7 @@ class Project
|
||||
public function setBudget($budget)
|
||||
{
|
||||
$this->budget = $budget;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -209,6 +213,7 @@ class Project
|
||||
public function setActivities($activities)
|
||||
{
|
||||
$this->activities = $activities;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -235,6 +240,7 @@ class Project
|
||||
public function setOrderNumber($orderNumber)
|
||||
{
|
||||
$this->orderNumber = $orderNumber;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Entity\User;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
@@ -29,9 +28,8 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
*/
|
||||
class Timesheet
|
||||
{
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
* @var int
|
||||
*
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
* @ORM\Id
|
||||
@@ -55,7 +53,7 @@ class Timesheet
|
||||
private $end;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
* @var int
|
||||
*
|
||||
* @ORM\Column(name="duration", type="integer", nullable=true)
|
||||
* @Assert\GreaterThanOrEqual(0)
|
||||
@@ -97,7 +95,7 @@ class Timesheet
|
||||
/**
|
||||
* Get entry id
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
@@ -119,6 +117,7 @@ class Timesheet
|
||||
public function setBegin($begin)
|
||||
{
|
||||
$this->begin = $begin;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -137,7 +136,7 @@ class Timesheet
|
||||
public function setEnd($end)
|
||||
{
|
||||
$this->end = $end;
|
||||
if ($end === null) {
|
||||
if (null === $end) {
|
||||
$this->duration = 0;
|
||||
}
|
||||
|
||||
@@ -147,12 +146,13 @@ class Timesheet
|
||||
/**
|
||||
* Set duration
|
||||
*
|
||||
* @param integer $duration
|
||||
* @param int $duration
|
||||
* @return Timesheet
|
||||
*/
|
||||
public function setDuration($duration)
|
||||
{
|
||||
$this->duration = $duration;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ class Timesheet
|
||||
* Get duration
|
||||
* Do not rely on the results of this method for active records.
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function getDuration()
|
||||
{
|
||||
@@ -176,6 +176,7 @@ class Timesheet
|
||||
public function setUser(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -198,6 +199,7 @@ class Timesheet
|
||||
public function setActivity($activity)
|
||||
{
|
||||
$this->activity = $activity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -220,6 +222,7 @@ class Timesheet
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -242,6 +245,7 @@ class Timesheet
|
||||
public function setRate($rate)
|
||||
{
|
||||
$this->rate = $rate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -263,7 +267,7 @@ class Timesheet
|
||||
*/
|
||||
public function validate(ExecutionContextInterface $context, $payload)
|
||||
{
|
||||
if ($this->getEnd() !== null && $this->getEnd()->getTimestamp() < $this->getBegin()->getTimestamp()) {
|
||||
if (null !== $this->getEnd() && $this->getEnd()->getTimestamp() < $this->getBegin()->getTimestamp()) {
|
||||
$context->buildViolation('End date must not be earlier then start date.')
|
||||
->atPath('end')
|
||||
->setTranslationDomain('validators')
|
||||
|
||||
@@ -6,7 +6,6 @@ use App\Validator\Constraints as KimaiAssert;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
@@ -27,12 +26,12 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
*/
|
||||
class User implements UserInterface
|
||||
{
|
||||
const ROLE_CUSTOMER = 'ROLE_CUSTOMER';
|
||||
const ROLE_USER = 'ROLE_USER';
|
||||
const ROLE_TEAMLEAD = 'ROLE_TEAMLEAD';
|
||||
const ROLE_ADMIN = 'ROLE_ADMIN';
|
||||
const ROLE_SUPER_ADMIN = 'ROLE_SUPER_ADMIN';
|
||||
const DEFAULT_ROLE = self::ROLE_USER;
|
||||
public const ROLE_CUSTOMER = 'ROLE_CUSTOMER';
|
||||
public const ROLE_USER = 'ROLE_USER';
|
||||
public const ROLE_TEAMLEAD = 'ROLE_TEAMLEAD';
|
||||
public const ROLE_ADMIN = 'ROLE_ADMIN';
|
||||
public const ROLE_SUPER_ADMIN = 'ROLE_SUPER_ADMIN';
|
||||
public const DEFAULT_ROLE = self::ROLE_USER;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
@@ -85,7 +84,7 @@ class User implements UserInterface
|
||||
private $alias;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
* @var bool
|
||||
*
|
||||
* @ORM\Column(name="active", type="boolean", nullable=false)
|
||||
* @Assert\NotNull()
|
||||
@@ -184,7 +183,7 @@ class User implements UserInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $active
|
||||
* @param bool $active
|
||||
* @return $this
|
||||
*/
|
||||
public function setActive($active)
|
||||
@@ -195,7 +194,7 @@ class User implements UserInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isActive()
|
||||
{
|
||||
@@ -242,6 +241,7 @@ class User implements UserInterface
|
||||
public function setPlainPassword($password)
|
||||
{
|
||||
$this->plainPassword = $password;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -279,6 +279,7 @@ class User implements UserInterface
|
||||
public function setEmail($email)
|
||||
{
|
||||
$this->email = $email;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -297,6 +298,7 @@ class User implements UserInterface
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -315,6 +317,7 @@ class User implements UserInterface
|
||||
public function setAvatar($avatar)
|
||||
{
|
||||
$this->avatar = $avatar;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -342,6 +345,7 @@ class User implements UserInterface
|
||||
public function setRoles(array $roles)
|
||||
{
|
||||
$this->roles = $roles;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -363,6 +367,7 @@ class User implements UserInterface
|
||||
$preferences = new ArrayCollection($preferences);
|
||||
}
|
||||
$this->preferences = $preferences;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -382,16 +387,17 @@ class User implements UserInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $default
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @return bool|int|null|string
|
||||
*/
|
||||
public function getPreferenceValue($name, $default = null)
|
||||
{
|
||||
$preference = $this->getPreference($name);
|
||||
if ($preference === null) {
|
||||
if (null === $preference) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $preference->getValue();
|
||||
}
|
||||
|
||||
@@ -402,6 +408,7 @@ class User implements UserInterface
|
||||
public function addPreference(UserPreference $preference)
|
||||
{
|
||||
$this->preferences->add($preference);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||
*/
|
||||
class UserPreference
|
||||
{
|
||||
const HOURLY_RATE = 'hourly_rate';
|
||||
const SKIN = 'skin';
|
||||
public const HOURLY_RATE = 'hourly_rate';
|
||||
public const SKIN = 'skin';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
@@ -82,6 +82,7 @@ class UserPreference
|
||||
public function setId(int $id): UserPreference
|
||||
{
|
||||
$this->id = $id;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -100,6 +101,7 @@ class UserPreference
|
||||
public function setUser(User $user): UserPreference
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -118,6 +120,7 @@ class UserPreference
|
||||
public function setName(string $name): UserPreference
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -143,6 +146,7 @@ class UserPreference
|
||||
public function setValue($value): UserPreference
|
||||
{
|
||||
$this->value = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -155,6 +159,7 @@ class UserPreference
|
||||
public function setType(string $type)
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -175,6 +180,7 @@ class UserPreference
|
||||
public function setConstraints(array $constraints)
|
||||
{
|
||||
$this->constraints = $constraints;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -187,6 +193,7 @@ class UserPreference
|
||||
public function addConstraint(Constraint $constraint)
|
||||
{
|
||||
$this->constraints[] = $constraint;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ use Avanzu\AdminThemeBundle\Model\MenuItemModel;
|
||||
*/
|
||||
class ConfigureAdminMenuEvent extends ConfigureMenuEvent
|
||||
{
|
||||
const CONFIGURE = 'app.admin_menu_configure';
|
||||
public const CONFIGURE = 'app.admin_menu_configure';
|
||||
|
||||
/**
|
||||
* This function will either return a MenuItem or null.
|
||||
|
||||
@@ -14,5 +14,5 @@ namespace App\Event;
|
||||
*/
|
||||
class ConfigureMainMenuEvent extends ConfigureMenuEvent
|
||||
{
|
||||
const CONFIGURE = 'app.main_menu_configure';
|
||||
public const CONFIGURE = 'app.main_menu_configure';
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ namespace App\Event;
|
||||
use Avanzu\AdminThemeBundle\Event\SidebarMenuEvent;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
|
||||
|
||||
/**
|
||||
* The ConfigureMenuEvent is used for populating navigations.
|
||||
|
||||
@@ -18,7 +18,7 @@ use Symfony\Component\EventDispatcher\Event;
|
||||
*/
|
||||
class UserPreferenceEvent extends Event
|
||||
{
|
||||
const CONFIGURE = 'app.user_preferences';
|
||||
public const CONFIGURE = 'app.user_preferences';
|
||||
|
||||
/**
|
||||
* @var User
|
||||
@@ -64,7 +64,7 @@ class UserPreferenceEvent extends Event
|
||||
foreach ($this->preferences as $pref) {
|
||||
if ($pref->getName() == $preference->getName()) {
|
||||
throw new \InvalidArgumentException(
|
||||
'Cannot add preference, a preference with the name "'.$preference->getName().'" is already existing'
|
||||
'Cannot add preference, one with the name "' . $preference->getName() . '" is already existing'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ class NavbarShowUserSubscriber implements EventSubscriberInterface
|
||||
*/
|
||||
public function onShowUser(ShowUserEvent $event)
|
||||
{
|
||||
if ($this->storage->getToken() === null) {
|
||||
if (null === $this->storage->getToken()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInt
|
||||
*/
|
||||
class ThemeOptionsSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var TokenStorageInterface
|
||||
*/
|
||||
@@ -69,11 +68,11 @@ class ThemeOptionsSubscriber implements EventSubscriberInterface
|
||||
$skin = '';
|
||||
foreach ($user->getPreferences() as $ref) {
|
||||
$name = $ref->getName();
|
||||
if ($name === UserPreference::SKIN) {
|
||||
if (UserPreference::SKIN === $name) {
|
||||
$skin = 'skin-' . $ref->getValue();
|
||||
}
|
||||
|
||||
if (strpos($name, 'theme.') !== false) {
|
||||
if (false !== strpos($name, 'theme.')) {
|
||||
$this->helper->setOption(str_replace('theme.', '', $name), $ref->getValue());
|
||||
}
|
||||
}
|
||||
@@ -97,7 +96,7 @@ class ThemeOptionsSubscriber implements EventSubscriberInterface
|
||||
}
|
||||
|
||||
// ignore events like the toolbar where we do not have a token
|
||||
if ($this->storage->getToken() === null) {
|
||||
if (null === $this->storage->getToken()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ use Symfony\Component\Validator\Constraints\Range;
|
||||
*/
|
||||
class UserPreferenceSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var EventDispatcherInterface
|
||||
*/
|
||||
@@ -127,7 +126,7 @@ class UserPreferenceSubscriber implements EventSubscriberInterface
|
||||
|
||||
foreach ($event->getPreferences() as $preference) {
|
||||
if (isset($prefs[$preference->getName()])) {
|
||||
/** @var UserPreference $pref */
|
||||
/* @var UserPreference $pref */
|
||||
$prefs[$preference->getName()]
|
||||
->setType($preference->getType())
|
||||
->setConstraints($preference->getConstraints())
|
||||
@@ -152,7 +151,7 @@ class UserPreferenceSubscriber implements EventSubscriberInterface
|
||||
}
|
||||
|
||||
// ignore events like the toolbar where we do not have a token
|
||||
if ($this->storage->getToken() === null) {
|
||||
if (null === $this->storage->getToken()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class ActivityEditForm extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -28,7 +28,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class CustomerEditForm extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -43,7 +43,7 @@ class DocumentationLinkExtension extends AbstractTypeExtension
|
||||
*/
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefined(array('documentation'));
|
||||
$resolver->setDefined(['documentation']);
|
||||
$resolver->setDefaults(['documentation' => null]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class InvoiceTemplateForm extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -26,7 +26,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class ProjectEditForm extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -25,7 +25,6 @@ use App\Repository\ActivityRepository;
|
||||
*/
|
||||
class TimesheetEditForm extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -39,7 +38,7 @@ class TimesheetEditForm extends AbstractType
|
||||
$activity = $entry->getActivity();
|
||||
}
|
||||
|
||||
if ($entry->getEnd() === null || !$options['duration_only']) {
|
||||
if (null === $entry->getEnd() || !$options['duration_only']) {
|
||||
$builder->add('begin', DateTimeType::class, [
|
||||
'label' => 'label.begin',
|
||||
'widget' => 'single_text',
|
||||
|
||||
@@ -33,7 +33,6 @@ use Symfony\Component\Form\FormEvents;
|
||||
*/
|
||||
abstract class AbstractToolbarForm extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* Dirty hack to enable easy handling of GET form in controller and javascript.
|
||||
*Cleans up the name of all form elents (and unfortunately of the form itself).
|
||||
@@ -67,6 +66,7 @@ abstract class AbstractToolbarForm extends AbstractType
|
||||
$query = new CustomerQuery();
|
||||
$query->setVisibility(CustomerQuery::SHOW_BOTH); // this field is the reason for the query here
|
||||
$query->setResultType(CustomerQuery::RESULT_TYPE_QUERYBUILDER);
|
||||
|
||||
return $repo->findByQuery($query);
|
||||
},
|
||||
]);
|
||||
@@ -147,6 +147,7 @@ abstract class AbstractToolbarForm extends AbstractType
|
||||
'query_builder' => function (ProjectRepository $repo) use ($data) {
|
||||
$qb = $repo->builderForEntityType();
|
||||
$qb->where('p.customer = :customer')->setParameter('customer', $data['customer']);
|
||||
|
||||
return $qb;
|
||||
},
|
||||
]);
|
||||
@@ -173,6 +174,7 @@ abstract class AbstractToolbarForm extends AbstractType
|
||||
'query_builder' => function (ActivityRepository $repo) use ($data) {
|
||||
$qb = $repo->builderForEntityType();
|
||||
$qb->where('a.project = :project')->setParameter('project', $data['project']);
|
||||
|
||||
return $qb;
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -18,7 +18,6 @@ use App\Repository\Query\ActivityQuery;
|
||||
*/
|
||||
class ActivityToolbarForm extends AbstractToolbarForm
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -18,7 +18,6 @@ use App\Repository\Query\CustomerQuery;
|
||||
*/
|
||||
class CustomerToolbarForm extends AbstractToolbarForm
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -19,9 +19,8 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class InvoiceToolbarForm extends AbstractToolbarForm
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,6 @@ use App\Repository\Query\ProjectQuery;
|
||||
*/
|
||||
class ProjectToolbarForm extends AbstractToolbarForm
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -16,9 +16,8 @@ use Symfony\Component\Form\FormBuilderInterface;
|
||||
*/
|
||||
class TimesheetAdminToolbarForm extends TimesheetToolbarForm
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
|
||||
@@ -19,9 +19,8 @@ use App\Repository\Query\TimesheetQuery;
|
||||
*/
|
||||
class TimesheetToolbarForm extends AbstractToolbarForm
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class UserToolbarForm extends AbstractToolbarForm
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -16,7 +16,6 @@ use App\Entity\Activity;
|
||||
*/
|
||||
class ActivityGroupedWithCustomerNameType extends ActivityType
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Activity $activity
|
||||
* @param $key
|
||||
|
||||
@@ -20,7 +20,6 @@ use App\Repository\ActivityRepository;
|
||||
*/
|
||||
class ActivityType extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -19,7 +19,6 @@ use App\Repository\CustomerRepository;
|
||||
*/
|
||||
class CustomerType extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -50,7 +50,6 @@ class DurationType extends AbstractType
|
||||
*/
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
|
||||
$resolver->setDefaults([
|
||||
'label' => 'label.duration',
|
||||
'constraints' => [new Regex(['pattern' => $this->pattern])],
|
||||
|
||||
@@ -19,7 +19,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class InvoiceTemplateType extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -19,7 +19,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class LanguageType extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -18,7 +18,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class PageSizeType extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,6 @@ use App\Repository\ProjectRepository;
|
||||
*/
|
||||
class ProjectType extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -18,7 +18,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class SkinType extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -23,7 +23,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class UserPreferenceType extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* @param FormBuilderInterface $builder
|
||||
* @param array $options
|
||||
@@ -43,7 +42,7 @@ class UserPreferenceType extends AbstractType
|
||||
}
|
||||
|
||||
$required = true;
|
||||
if ($preference->getType() == CheckboxType::class) {
|
||||
if (CheckboxType::class == $preference->getType()) {
|
||||
$required = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class UserRoleType extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
@@ -39,7 +38,7 @@ class UserRoleType extends AbstractType
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$roles = [];
|
||||
|
||||
/* @var string[] $value */
|
||||
foreach ($this->roles as $key => $value) {
|
||||
$roles[$key] = $key;
|
||||
foreach ($value as $value2) {
|
||||
|
||||
@@ -19,7 +19,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class UserType extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -32,6 +31,7 @@ class UserType extends AbstractType
|
||||
if (!empty($user->getAlias())) {
|
||||
return $user->getAlias() . ' (' . $user->getUsername() . ')';
|
||||
}
|
||||
|
||||
return $user->getUsername();
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -19,7 +19,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class VisibilityType extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -18,7 +18,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class YesNoType extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -19,7 +19,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class UserCreateType extends UserEditType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Form\Type\LanguageType;
|
||||
use App\Form\Type\YesNoType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
@@ -22,7 +21,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class UserEditType extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -21,7 +21,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class UserPasswordType extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -30,7 +29,7 @@ class UserPasswordType extends AbstractType
|
||||
$builder
|
||||
->add('plainPassword', RepeatedType::class, [
|
||||
'type' => PasswordType::class,
|
||||
'first_options' => ['label' => 'label.password'],
|
||||
'first_options' => ['label' => 'label.password'],
|
||||
'second_options' => ['label' => 'label.password_repeat'],
|
||||
])
|
||||
;
|
||||
|
||||
@@ -21,7 +21,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class UserPreferencesForm extends AbstractType
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -17,7 +17,6 @@ use App\Model\InvoiceModel;
|
||||
*/
|
||||
interface CalculatorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Return the timesheet records that will be displayed on the invoice.
|
||||
*
|
||||
|
||||
@@ -20,7 +20,6 @@ use App\Model\InvoiceModel;
|
||||
*/
|
||||
class DefaultCalculator implements CalculatorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
@@ -56,6 +55,7 @@ class DefaultCalculator implements CalculatorInterface
|
||||
foreach ($this->model->getEntries() as $entry) {
|
||||
$amount += $entry->getRate();
|
||||
}
|
||||
|
||||
return round($amount, 2);
|
||||
}
|
||||
|
||||
@@ -73,11 +73,12 @@ class DefaultCalculator implements CalculatorInterface
|
||||
public function getTax(): float
|
||||
{
|
||||
$vat = $this->getVat();
|
||||
if ($vat == 0) {
|
||||
if (0 == $vat) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$percent = $vat / 100.00;
|
||||
|
||||
return round($this->getSubtotal() * $percent, 2);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ use App\Model\InvoiceModel;
|
||||
*/
|
||||
interface NumberGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param InvoiceModel $model
|
||||
*/
|
||||
|
||||
@@ -50,6 +50,7 @@ class ServiceInvoice
|
||||
return new $class();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -72,6 +73,7 @@ class ServiceInvoice
|
||||
return new $class();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -97,6 +99,7 @@ class ServiceInvoice
|
||||
return $action;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ use App\Entity\Timesheet;
|
||||
*/
|
||||
class ShortInvoiceCalculator extends DefaultCalculator
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Timesheet[]
|
||||
*/
|
||||
@@ -28,7 +27,7 @@ class ShortInvoiceCalculator extends DefaultCalculator
|
||||
foreach ($this->model->getEntries() as $entry) {
|
||||
$timesheet->setRate($timesheet->getRate() + $entry->getRate());
|
||||
$timesheet->setDuration($timesheet->getDuration() + $entry->getDuration());
|
||||
if ($timesheet->getActivity() === null) {
|
||||
if (null === $timesheet->getActivity()) {
|
||||
$timesheet->setActivity($entry->getActivity());
|
||||
$timesheet->setEnd($entry->getEnd());
|
||||
}
|
||||
|
||||
@@ -23,16 +23,16 @@ class Kernel extends BaseKernel
|
||||
{
|
||||
use MicroKernelTrait;
|
||||
|
||||
const CONFIG_EXTS = '.{php,xml,yaml,yml}';
|
||||
public const CONFIG_EXTS = '.{php,xml,yaml,yml}';
|
||||
|
||||
public function getCacheDir()
|
||||
{
|
||||
return $this->getProjectDir().'/var/cache/'.$this->environment;
|
||||
return $this->getProjectDir() . '/var/cache/' . $this->environment;
|
||||
}
|
||||
|
||||
public function getLogDir()
|
||||
{
|
||||
return $this->getProjectDir().'/var/log';
|
||||
return $this->getProjectDir() . '/var/log';
|
||||
}
|
||||
|
||||
protected function build(ContainerBuilder $container)
|
||||
@@ -42,7 +42,7 @@ class Kernel extends BaseKernel
|
||||
|
||||
public function registerBundles()
|
||||
{
|
||||
$contents = require $this->getProjectDir().'/config/bundles.php';
|
||||
$contents = require $this->getProjectDir() . '/config/bundles.php';
|
||||
foreach ($contents as $class => $envs) {
|
||||
if (isset($envs['all']) || isset($envs[$this->environment])) {
|
||||
yield new $class();
|
||||
@@ -56,27 +56,27 @@ class Kernel extends BaseKernel
|
||||
|
||||
$container->setParameter('container.autowiring.strict_mode', true);
|
||||
$container->setParameter('container.dumper.inline_class_loader', true);
|
||||
$confDir = $this->getProjectDir().'/config';
|
||||
$loader->load($confDir.'/packages/*'.self::CONFIG_EXTS, 'glob');
|
||||
if (is_dir($confDir.'/packages/'.$this->environment)) {
|
||||
$loader->load($confDir.'/packages/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob');
|
||||
$confDir = $this->getProjectDir() . '/config';
|
||||
$loader->load($confDir . '/packages/*' . self::CONFIG_EXTS, 'glob');
|
||||
if (is_dir($confDir . '/packages/' . $this->environment)) {
|
||||
$loader->load($confDir . '/packages/' . $this->environment . '/**/*' . self::CONFIG_EXTS, 'glob');
|
||||
}
|
||||
$loader->load($confDir.'/packages/local'.self::CONFIG_EXTS, 'glob');
|
||||
$loader->load($confDir.'/services'.self::CONFIG_EXTS, 'glob');
|
||||
$loader->load($confDir.'/services_'.$this->environment.self::CONFIG_EXTS, 'glob');
|
||||
$loader->load($confDir . '/packages/local' . self::CONFIG_EXTS, 'glob');
|
||||
$loader->load($confDir . '/services' . self::CONFIG_EXTS, 'glob');
|
||||
$loader->load($confDir . '/services_' . $this->environment . self::CONFIG_EXTS, 'glob');
|
||||
|
||||
$container->addCompilerPass(new DoctrineCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -1000);
|
||||
}
|
||||
|
||||
protected function configureRoutes(RouteCollectionBuilder $routes)
|
||||
{
|
||||
$confDir = $this->getProjectDir().'/config';
|
||||
if (is_dir($confDir.'/routes/')) {
|
||||
$routes->import($confDir.'/routes/*'.self::CONFIG_EXTS, '/', 'glob');
|
||||
$confDir = $this->getProjectDir() . '/config';
|
||||
if (is_dir($confDir . '/routes/')) {
|
||||
$routes->import($confDir . '/routes/*' . self::CONFIG_EXTS, '/', 'glob');
|
||||
}
|
||||
if (is_dir($confDir.'/routes/'.$this->environment)) {
|
||||
$routes->import($confDir.'/routes/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob');
|
||||
if (is_dir($confDir . '/routes/' . $this->environment)) {
|
||||
$routes->import($confDir . '/routes/' . $this->environment . '/**/*' . self::CONFIG_EXTS, '/', 'glob');
|
||||
}
|
||||
$routes->import($confDir.'/routes'.self::CONFIG_EXTS, '/', 'glob');
|
||||
$routes->import($confDir . '/routes' . self::CONFIG_EXTS, '/', 'glob');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ class ActivityStatistic
|
||||
public function setRecordAmount($recordAmount)
|
||||
{
|
||||
$this->recordAmount = (int) $recordAmount;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -64,6 +65,7 @@ class ActivityStatistic
|
||||
public function setRecordDuration($recordDuration)
|
||||
{
|
||||
$this->recordDuration = (int) $recordDuration;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -84,6 +86,7 @@ class ActivityStatistic
|
||||
public function setCount($count)
|
||||
{
|
||||
$this->count = (int) $count;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ class CustomerStatistic
|
||||
public function setRecordAmount($recordAmount)
|
||||
{
|
||||
$this->recordAmount = (int) $recordAmount;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -72,6 +73,7 @@ class CustomerStatistic
|
||||
public function setRecordDuration($recordDuration)
|
||||
{
|
||||
$this->recordDuration = (int) $recordDuration;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -92,6 +94,7 @@ class CustomerStatistic
|
||||
public function setCount($count)
|
||||
{
|
||||
$this->count = (int) $count;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -110,6 +113,7 @@ class CustomerStatistic
|
||||
public function setActivityAmount($activityAmount)
|
||||
{
|
||||
$this->activityAmount = (int) $activityAmount;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -128,6 +132,7 @@ class CustomerStatistic
|
||||
public function setProjectAmount($projectAmount)
|
||||
{
|
||||
$this->projectAmount = (int) $projectAmount;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,6 @@ use App\Entity\Customer;
|
||||
use App\Entity\InvoiceTemplate;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Invoice\CalculatorInterface;
|
||||
use App\Invoice\DateNumberGenerator;
|
||||
use App\Invoice\DefaultCalculator;
|
||||
use App\Invoice\NumberGeneratorInterface;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
|
||||
@@ -23,7 +21,6 @@ use App\Repository\Query\InvoiceQuery;
|
||||
*/
|
||||
class InvoiceModel
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Customer
|
||||
*/
|
||||
@@ -69,6 +66,7 @@ class InvoiceModel
|
||||
public function setQuery(InvoiceQuery $query)
|
||||
{
|
||||
$this->query = $query;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -89,6 +87,7 @@ class InvoiceModel
|
||||
public function setEntries(array $entries)
|
||||
{
|
||||
$this->entries = $entries;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -107,6 +106,7 @@ class InvoiceModel
|
||||
public function setTemplate($template)
|
||||
{
|
||||
$this->template = $template;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@ class InvoiceModel
|
||||
public function setCustomer($customer)
|
||||
{
|
||||
$this->customer = $customer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -133,7 +134,7 @@ class InvoiceModel
|
||||
*/
|
||||
public function getDueDate(): \DateTime
|
||||
{
|
||||
return new \DateTime('+'.$this->getTemplate()->getDueDays().' days');
|
||||
return new \DateTime('+' . $this->getTemplate()->getDueDays() . ' days');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,6 +153,7 @@ class InvoiceModel
|
||||
{
|
||||
$this->generator = $generator;
|
||||
$this->generator->setModel($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -171,6 +173,7 @@ class InvoiceModel
|
||||
{
|
||||
$this->calculator = $calculator;
|
||||
$this->calculator->setModel($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ class ProjectStatistic
|
||||
public function setRecordAmount($recordAmount)
|
||||
{
|
||||
$this->recordAmount = (int) $recordAmount;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -68,6 +69,7 @@ class ProjectStatistic
|
||||
public function setRecordDuration($recordDuration)
|
||||
{
|
||||
$this->recordDuration = (int) $recordDuration;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -88,6 +90,7 @@ class ProjectStatistic
|
||||
public function setCount($count)
|
||||
{
|
||||
$this->count = (int) $count;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -106,6 +109,7 @@ class ProjectStatistic
|
||||
public function setActivityAmount($activityAmount)
|
||||
{
|
||||
$this->activityAmount = (int) $activityAmount;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ class Month
|
||||
public function setTotalDuration($totalDuration)
|
||||
{
|
||||
$this->totalDuration = $totalDuration;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -77,6 +78,7 @@ class Month
|
||||
public function setTotalRate($totalRate)
|
||||
{
|
||||
$this->totalRate = $totalRate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class Year
|
||||
*/
|
||||
public function setMonth(Month $month)
|
||||
{
|
||||
$this->months[(int)$month->getMonth()] = $month;
|
||||
$this->months[(int) $month->getMonth()] = $month;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace App\Model;
|
||||
|
||||
use \DateTime;
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* Timesheet statistics for one user.
|
||||
|
||||
@@ -9,12 +9,7 @@
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Repository\Query\BaseQuery;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Pagerfanta\Adapter\DoctrineORMAdapter;
|
||||
use Pagerfanta\Pagerfanta;
|
||||
|
||||
/**
|
||||
* Class AbstractRepository
|
||||
|
||||
@@ -21,7 +21,6 @@ use App\Repository\Query\ActivityQuery;
|
||||
*/
|
||||
class ActivityRepository extends AbstractRepository
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return null|Activity
|
||||
@@ -55,12 +54,12 @@ class ActivityRepository extends AbstractRepository
|
||||
->setMaxResults(10)
|
||||
;
|
||||
|
||||
if ($user !== null) {
|
||||
if (null !== $user) {
|
||||
$qb->andWhere('t.user = :user')
|
||||
->setParameter('user', $user);
|
||||
}
|
||||
|
||||
if ($startFrom !== null) {
|
||||
if (null !== $startFrom) {
|
||||
$qb->andWhere($qb->expr()->gt('t.begin', ':begin'))
|
||||
->setParameter('begin', $startFrom);
|
||||
}
|
||||
@@ -85,7 +84,7 @@ class ActivityRepository extends AbstractRepository
|
||||
public function getGlobalStatistics()
|
||||
{
|
||||
$countAll = $this->getEntityManager()
|
||||
->createQuery('SELECT COUNT(a.id) FROM '.Activity::class.' a')
|
||||
->createQuery('SELECT COUNT(a.id) FROM ' . Activity::class . ' a')
|
||||
->getSingleScalarResult();
|
||||
|
||||
$stats = new ActivityStatistic();
|
||||
@@ -135,6 +134,7 @@ class ActivityRepository extends AbstractRepository
|
||||
$query = new ActivityQuery();
|
||||
$query->setHiddenEntity($entity);
|
||||
$query->setResultType(ActivityQuery::RESULT_TYPE_QUERYBUILDER);
|
||||
|
||||
return $this->findByQuery($query);
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ class ActivityRepository extends AbstractRepository
|
||||
->join('p.customer', 'c')
|
||||
->orderBy('a.' . $query->getOrderBy(), $query->getOrder());
|
||||
|
||||
if ($query->getVisibility() == ActivityQuery::SHOW_VISIBLE) {
|
||||
if (ActivityQuery::SHOW_VISIBLE == $query->getVisibility()) {
|
||||
if (!$query->isExclusiveVisibility()) {
|
||||
$qb->andWhere('c.visible = 1');
|
||||
$qb->andWhere('p.visible = 1');
|
||||
@@ -161,17 +161,17 @@ class ActivityRepository extends AbstractRepository
|
||||
|
||||
/** @var Activity $entity */
|
||||
$entity = $query->getHiddenEntity();
|
||||
if ($entity !== null) {
|
||||
if (null !== $entity) {
|
||||
$qb->orWhere('a.id = :activity')->setParameter('activity', $entity);
|
||||
}
|
||||
} elseif ($query->getVisibility() == ActivityQuery::SHOW_HIDDEN) {
|
||||
} elseif (ActivityQuery::SHOW_HIDDEN == $query->getVisibility()) {
|
||||
$qb->andWhere('a.visible = 0');
|
||||
}
|
||||
|
||||
if ($query->getProject() !== null) {
|
||||
if (null !== $query->getProject()) {
|
||||
$qb->andWhere('a.project = :project')
|
||||
->setParameter('project', $query->getProject());
|
||||
} elseif ($query->getCustomer() !== null) {
|
||||
} elseif (null !== $query->getCustomer()) {
|
||||
$qb->andWhere('p.customer = :customer')
|
||||
->setParameter('customer', $query->getCustomer());
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ use App\Repository\Query\CustomerQuery;
|
||||
*/
|
||||
class CustomerRepository extends AbstractRepository
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return null|Customer
|
||||
@@ -41,11 +40,12 @@ class CustomerRepository extends AbstractRepository
|
||||
public function getGlobalStatistics()
|
||||
{
|
||||
$countAll = $this->getEntityManager()
|
||||
->createQuery('SELECT COUNT(c.id) FROM '.Customer::class.' c')
|
||||
->createQuery('SELECT COUNT(c.id) FROM ' . Customer::class . ' c')
|
||||
->getSingleScalarResult();
|
||||
|
||||
$stats = new CustomerStatistic();
|
||||
$stats->setCount($countAll);
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
@@ -101,6 +101,7 @@ class CustomerRepository extends AbstractRepository
|
||||
$query = new CustomerQuery();
|
||||
$query->setHiddenEntity($entity);
|
||||
$query->setResultType(CustomerQuery::RESULT_TYPE_QUERYBUILDER);
|
||||
|
||||
return $this->findByQuery($query);
|
||||
}
|
||||
|
||||
@@ -116,15 +117,15 @@ class CustomerRepository extends AbstractRepository
|
||||
->from(Customer::class, 'c')
|
||||
->orderBy('c.' . $query->getOrderBy(), $query->getOrder());
|
||||
|
||||
if ($query->getVisibility() == CustomerQuery::SHOW_VISIBLE) {
|
||||
if (CustomerQuery::SHOW_VISIBLE == $query->getVisibility()) {
|
||||
$qb->andWhere('c.visible = 1');
|
||||
|
||||
/** @var Customer $entity */
|
||||
$entity = $query->getHiddenEntity();
|
||||
if ($entity!== null) {
|
||||
if (null !== $entity) {
|
||||
$qb->orWhere('c.id = :customer')->setParameter('customer', $entity);
|
||||
}
|
||||
} elseif ($query->getVisibility() == CustomerQuery::SHOW_HIDDEN) {
|
||||
} elseif (CustomerQuery::SHOW_HIDDEN == $query->getVisibility()) {
|
||||
$qb->andWhere('c.visible = 0');
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ use Doctrine\ORM\Query;
|
||||
*/
|
||||
class InvoiceTemplateRepository extends AbstractRepository
|
||||
{
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
@@ -21,7 +21,6 @@ use App\Repository\Query\ProjectQuery;
|
||||
*/
|
||||
class ProjectRepository extends AbstractRepository
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return null|Project
|
||||
@@ -40,11 +39,12 @@ class ProjectRepository extends AbstractRepository
|
||||
public function getGlobalStatistics()
|
||||
{
|
||||
$countAll = $this->getEntityManager()
|
||||
->createQuery('SELECT COUNT(p.id) FROM '.Project::class.' p')
|
||||
->createQuery('SELECT COUNT(p.id) FROM ' . Project::class . ' p')
|
||||
->getSingleScalarResult();
|
||||
|
||||
$stats = new ProjectStatistic();
|
||||
$stats->setCount($countAll);
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ class ProjectRepository extends AbstractRepository
|
||||
$query = new ProjectQuery();
|
||||
$query->setHiddenEntity($entity);
|
||||
$query->setResultType(ProjectQuery::RESULT_TYPE_QUERYBUILDER);
|
||||
|
||||
return $this->findByQuery($query);
|
||||
}
|
||||
|
||||
@@ -112,7 +113,7 @@ class ProjectRepository extends AbstractRepository
|
||||
->join('p.customer', 'c')
|
||||
->orderBy('p.' . $query->getOrderBy(), $query->getOrder());
|
||||
|
||||
if ($query->getVisibility() == ProjectQuery::SHOW_VISIBLE) {
|
||||
if (ProjectQuery::SHOW_VISIBLE == $query->getVisibility()) {
|
||||
if (!$query->isExclusiveVisibility()) {
|
||||
$qb->andWhere('c.visible = 1');
|
||||
}
|
||||
@@ -120,17 +121,17 @@ class ProjectRepository extends AbstractRepository
|
||||
|
||||
/** @var Project $entity */
|
||||
$entity = $query->getHiddenEntity();
|
||||
if ($entity !== null) {
|
||||
if (null !== $entity) {
|
||||
$qb->orWhere('p.id = :project')->setParameter('project', $entity);
|
||||
}
|
||||
|
||||
// TODO check for visibility of customer
|
||||
} elseif ($query->getVisibility() == ProjectQuery::SHOW_HIDDEN) {
|
||||
} elseif (ProjectQuery::SHOW_HIDDEN == $query->getVisibility()) {
|
||||
$qb->andWhere('p.visible = 0');
|
||||
// TODO check for visibility of customer
|
||||
}
|
||||
|
||||
if ($query->getCustomer() !== null) {
|
||||
if (null !== $query->getCustomer()) {
|
||||
$qb->andWhere('p.customer = :customer')
|
||||
->setParameter('customer', $query->getCustomer());
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
namespace App\Repository\Query;
|
||||
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
|
||||
/**
|
||||
@@ -17,7 +16,6 @@ use App\Entity\Project;
|
||||
*/
|
||||
class ActivityQuery extends ProjectQuery
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Project
|
||||
*/
|
||||
@@ -38,6 +36,7 @@ class ActivityQuery extends ProjectQuery
|
||||
public function setProject(Project $project = null)
|
||||
{
|
||||
$this->project = $project;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,17 +14,17 @@ namespace App\Repository\Query;
|
||||
*/
|
||||
class BaseQuery
|
||||
{
|
||||
const ORDER_ASC = 'ASC';
|
||||
const ORDER_DESC = 'DESC';
|
||||
public const ORDER_ASC = 'ASC';
|
||||
public const ORDER_DESC = 'DESC';
|
||||
|
||||
const DEFAULT_PAGESIZE = 25;
|
||||
const DEFAULT_PAGE = 1;
|
||||
public const DEFAULT_PAGESIZE = 25;
|
||||
public const DEFAULT_PAGE = 1;
|
||||
|
||||
const RESULT_TYPE_PAGER = 'PagerFanta';
|
||||
const RESULT_TYPE_QUERYBUILDER = 'QueryBuilder';
|
||||
public const RESULT_TYPE_PAGER = 'PagerFanta';
|
||||
public const RESULT_TYPE_QUERYBUILDER = 'QueryBuilder';
|
||||
|
||||
/**
|
||||
* @var \stdClass
|
||||
* @var object
|
||||
*/
|
||||
protected $hiddenEntity;
|
||||
/**
|
||||
@@ -62,7 +62,8 @@ class BaseQuery
|
||||
*/
|
||||
public function setPage($page)
|
||||
{
|
||||
$this->page = (int)$page;
|
||||
$this->page = (int) $page;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -80,9 +81,10 @@ class BaseQuery
|
||||
*/
|
||||
public function setPageSize($pageSize)
|
||||
{
|
||||
if (!empty($pageSize) && (int)$pageSize > 0) {
|
||||
$this->pageSize = (int)$pageSize;
|
||||
if (!empty($pageSize) && (int) $pageSize > 0) {
|
||||
$this->pageSize = (int) $pageSize;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -103,6 +105,7 @@ class BaseQuery
|
||||
public function setOrderBy($orderBy)
|
||||
{
|
||||
$this->orderBy = $orderBy;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -123,6 +126,7 @@ class BaseQuery
|
||||
if (in_array($order, [self::ORDER_ASC, self::ORDER_DESC])) {
|
||||
$this->order = $order;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -143,11 +147,12 @@ class BaseQuery
|
||||
if (in_array($resultType, [self::RESULT_TYPE_PAGER, self::RESULT_TYPE_QUERYBUILDER])) {
|
||||
$this->resultType = $resultType;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \stdClass
|
||||
* @return object
|
||||
*/
|
||||
public function getHiddenEntity()
|
||||
{
|
||||
@@ -155,12 +160,13 @@ class BaseQuery
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass $hiddenEntity
|
||||
* @param object $hiddenEntity
|
||||
* @return BaseQuery
|
||||
*/
|
||||
public function setHiddenEntity($hiddenEntity)
|
||||
{
|
||||
$this->hiddenEntity = $hiddenEntity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ use App\Entity\InvoiceTemplate;
|
||||
*/
|
||||
class InvoiceQuery extends TimesheetQuery
|
||||
{
|
||||
|
||||
/**
|
||||
* @var InvoiceTemplate
|
||||
*/
|
||||
@@ -42,6 +41,7 @@ class InvoiceQuery extends TimesheetQuery
|
||||
public function setTemplate($template)
|
||||
{
|
||||
$this->template = $template;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ class InvoiceQuery extends TimesheetQuery
|
||||
public function setTemplates(array $templates)
|
||||
{
|
||||
$this->templates = $templates;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ use App\Entity\Customer;
|
||||
*/
|
||||
class ProjectQuery extends VisibilityQuery
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Customer
|
||||
*/
|
||||
@@ -37,6 +36,7 @@ class ProjectQuery extends VisibilityQuery
|
||||
public function setCustomer(Customer $customer = null)
|
||||
{
|
||||
$this->customer = $customer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,19 +10,16 @@
|
||||
namespace App\Repository\Query;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Repository\Query\BaseQuery;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
|
||||
/**
|
||||
* Can be used for advanced timesheet repository queries.
|
||||
*/
|
||||
class TimesheetQuery extends ActivityQuery
|
||||
{
|
||||
const STATE_ALL = 1;
|
||||
const STATE_RUNNING = 2;
|
||||
const STATE_STOPPED = 3;
|
||||
public const STATE_ALL = 1;
|
||||
public const STATE_RUNNING = 2;
|
||||
public const STATE_STOPPED = 3;
|
||||
|
||||
/**
|
||||
* Overwritten for different default order
|
||||
@@ -70,6 +67,7 @@ class TimesheetQuery extends ActivityQuery
|
||||
public function setUser(User $user = null)
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -90,6 +88,7 @@ class TimesheetQuery extends ActivityQuery
|
||||
public function setActivity(Activity $activity = null)
|
||||
{
|
||||
$this->activity = $activity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -134,6 +133,7 @@ class TimesheetQuery extends ActivityQuery
|
||||
public function setBegin($begin)
|
||||
{
|
||||
$this->begin = $begin;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -152,6 +152,7 @@ class TimesheetQuery extends ActivityQuery
|
||||
public function setEnd($end)
|
||||
{
|
||||
$this->end = $end;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ namespace App\Repository\Query;
|
||||
*/
|
||||
class UserQuery extends VisibilityQuery
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
@@ -34,9 +33,10 @@ class UserQuery extends VisibilityQuery
|
||||
*/
|
||||
public function setRole($role)
|
||||
{
|
||||
if (strpos($role, 'ROLE_') !== false || $role === null) {
|
||||
if (false !== strpos($role, 'ROLE_') || null === $role) {
|
||||
$this->role = $role;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,12 +14,12 @@ namespace App\Repository\Query;
|
||||
*/
|
||||
class VisibilityQuery extends BaseQuery
|
||||
{
|
||||
const SHOW_VISIBLE = 1;
|
||||
const SHOW_HIDDEN = 2;
|
||||
const SHOW_BOTH = 3;
|
||||
public const SHOW_VISIBLE = 1;
|
||||
public const SHOW_HIDDEN = 2;
|
||||
public const SHOW_BOTH = 3;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
* @var int
|
||||
*/
|
||||
protected $visibility = self::SHOW_VISIBLE;
|
||||
/**
|
||||
@@ -70,6 +70,7 @@ class VisibilityQuery extends BaseQuery
|
||||
public function setExclusiveVisibility($exclusiveVisibility)
|
||||
{
|
||||
$this->exclusiveVisibility = (bool) $exclusiveVisibility;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user