composer prod dependencies and commands (#986)

This commit is contained in:
Kevin Papst
2019-08-01 23:21:43 +02:00
committed by GitHub
parent b0e03bb0b8
commit 8e06f94bdd
8 changed files with 638 additions and 764 deletions

View File

@@ -1,151 +0,0 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Command;
use App\Entity\Timesheet;
use App\Repository\TimesheetRepository;
use Doctrine\DBAL\Types\DateTimeType;
use Doctrine\DBAL\Types\Type;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
* This command was added with v0.8.
* Kimai saved the DateTime before with the local timezone, which can cause big problems when used in different environments.
* You should convert all timesheet records that were saved with Kimai 2 directly, but NOT the ones migrated from Kimai v1.
*
* Please read https://github.com/kevinpapst/kimai2/pull/372 to find out more!
*
* @codeCoverageIgnore
*/
class ConvertTimezoneCommand extends Command
{
/**
* @var TimesheetRepository
*/
protected $repository;
/**
* @param TimesheetRepository $repository
*/
public function __construct(TimesheetRepository $repository)
{
$this->repository = $repository;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('kimai:convert-timezone')
->setDescription('Convert timesheet dates between timezones, only made for updates from 0.7 to 0.8')
->setHelp('This command should only be required if you imported data from Kimai v1')
->addOption('first-id', 'f', InputArgument::OPTIONAL, 'The database ID which should be converted first')
->addOption('last-id', 'l', InputArgument::OPTIONAL, 'The database ID which should be converted last')
;
}
/**
* @param null|string $start
* @param null|string $end
* @return Timesheet[]
*/
protected function getTimesheets($start = null, $end = null)
{
$qb = $this->repository->createQueryBuilder('t');
$qb->select('t');
if (!empty($start)) {
$qb->andWhere($qb->expr()->gte('t.id', $start));
}
if (!empty($end)) {
$qb->andWhere($qb->expr()->lte('t.id', $end));
}
return $qb->getQuery()->getResult();
}
/**
* @param Timesheet $timesheet
* @param \DateTimeZone $timeZone
* @return Timesheet
*/
protected function convertTimesheet(Timesheet $timesheet, \DateTimeZone $timeZone): Timesheet
{
$oldTimezone = $timesheet->getTimezone();
if (null !== $timesheet->getBegin()) {
$beginDate = clone $timesheet->getBegin();
$beginDate->setTimezone($timeZone);
$timesheet->setBegin($beginDate);
}
if (null !== $timesheet->getEnd()) {
$endDate = clone $timesheet->getEnd();
$endDate->setTimezone($timeZone);
$timesheet->setEnd($endDate);
}
$timesheet->setTimezone($oldTimezone);
return $timesheet;
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
Type::overrideType(Type::DATETIME, DateTimeType::class);
$io = new SymfonyStyle($input, $output);
$start = $input->getOption('first-id');
$end = $input->getOption('last-id');
$result = $this->getTimesheets($start, $end);
$amount = count($result);
$answer = $io->ask(sprintf('This will update %s timesheet records, continue (y/n) ? ', $amount), 'y');
if ('y' !== $answer) {
$io->text('Aborting.');
return 1;
}
$utc = new \DateTimeZone('UTC');
$i = 0;
/** @var Timesheet $timesheet */
foreach ($result as $timesheet) {
$timesheet = $this->convertTimesheet($timesheet, $utc);
$this->repository->save($timesheet);
if (++$i % 80 === 0) {
$io->writeln('. (' . $i . '/' . $amount . ')');
} else {
$io->write('.');
}
}
$io->writeln('. (' . $i . '/' . $amount . ')');
$io->writeln('');
return 0;
}
}

View File

@@ -51,6 +51,14 @@ class CreateReleaseCommand extends Command
->addOption('directory', null, InputOption::VALUE_OPTIONAL, 'Directory where the release package will be stored', 'var/data/')
->addOption('release', null, InputOption::VALUE_OPTIONAL, 'The version that should be zipped', Constants::VERSION)
;
/*
* Hide this command in production.
* Maybe it should be de-activated completely?!
*/
if (getenv('APP_ENV') === 'prod') {
$this->setHidden(true);
}
}
/**

View File

@@ -9,6 +9,7 @@
namespace App\Command;
use Exception;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\ArrayInput;
@@ -46,6 +47,17 @@ EOT
;
}
/**
* Make sure that this command CANNOT be executed in production.
* It can't work, as the fixtures bundle is not available in production.
*
* @return bool
*/
public function isEnabled()
{
return getenv('APP_ENV') !== 'prod';
}
/**
* @param InputInterface $input
* @param OutputInterface $output
@@ -55,17 +67,11 @@ EOT
{
$io = new SymfonyStyle($input, $output);
if (getenv('APP_ENV') === 'prod') {
$io->error('kimai:reset-dev is not allowed in production');
return -1;
}
if ($this->askConfirmation($input, $output, 'Do you want to create the database y/N ?')) {
try {
$command = $this->getApplication()->find('doctrine:database:create');
$command->run(new ArrayInput([]), $output);
} catch (\Exception $ex) {
} catch (Exception $ex) {
$io->error('Failed to create database: ' . $ex->getMessage());
return 1;
@@ -76,7 +82,7 @@ EOT
try {
$command = $this->getApplication()->find('doctrine:schema:drop');
$command->run(new ArrayInput(['--force' => true]), $output);
} catch (\Exception $ex) {
} catch (Exception $ex) {
$io->error('Failed to drop database schema: ' . $ex->getMessage());
return 2;
@@ -85,7 +91,7 @@ EOT
try {
$command = $this->getApplication()->find('doctrine:schema:create');
$command->run(new ArrayInput([]), $output);
} catch (\Exception $ex) {
} catch (Exception $ex) {
$io->error('Failed to create database schema: ' . $ex->getMessage());
return 3;
@@ -97,7 +103,7 @@ EOT
$cmdInput = new ArrayInput([]);
$cmdInput->setInteractive(false);
$command->run($cmdInput, $output);
} catch (\Exception $ex) {
} catch (Exception $ex) {
$io->error('Failed to import fixtures: ' . $ex->getMessage());
return 4;
@@ -108,7 +114,7 @@ EOT
$cmdInput = new ArrayInput(['--add' => true, '--all' => true]);
$cmdInput->setInteractive(false);
$command->run($cmdInput, $output);
} catch (\Exception $ex) {
} catch (Exception $ex) {
$io->error('Failed to set migration status: ' . $ex->getMessage());
return 5;
@@ -118,7 +124,7 @@ EOT
$command = $this->getApplication()->find('cache:clear');
try {
$command->run(new ArrayInput([]), $output);
} catch (\Exception $ex) {
} catch (Exception $ex) {
$io->error('Failed to clear cache: ' . $ex->getMessage());
return 6;

View File

@@ -9,6 +9,8 @@
namespace App\Entity;
use DateTime;
use DateTimeZone;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
@@ -48,7 +50,7 @@ class Timesheet implements EntityWithMetaFields
private $id;
/**
* @var \DateTime
* @var DateTime
*
* @ORM\Column(name="start_time", type="datetime", nullable=false)
* @Assert\NotNull()
@@ -56,7 +58,7 @@ class Timesheet implements EntityWithMetaFields
private $begin;
/**
* @var \DateTime
* @var DateTime
*
* @ORM\Column(name="end_time", type="datetime", nullable=true)
*/
@@ -188,17 +190,17 @@ class Timesheet implements EntityWithMetaFields
}
if (null !== $this->begin) {
$this->begin->setTimeZone(new \DateTimeZone($this->timezone));
$this->begin->setTimeZone(new DateTimeZone($this->timezone));
}
if (null !== $this->end) {
$this->end->setTimeZone(new \DateTimeZone($this->timezone));
$this->end->setTimeZone(new DateTimeZone($this->timezone));
}
$this->localized = true;
}
public function getBegin(): ?\DateTime
public function getBegin(): ?DateTime
{
$this->localizeDates();
@@ -206,10 +208,10 @@ class Timesheet implements EntityWithMetaFields
}
/**
* @param \DateTime $begin
* @param DateTime $begin
* @return Timesheet
*/
public function setBegin(\DateTime $begin): Timesheet
public function setBegin(DateTime $begin): Timesheet
{
$this->begin = $begin;
$this->timezone = $begin->getTimezone()->getName();
@@ -217,7 +219,7 @@ class Timesheet implements EntityWithMetaFields
return $this;
}
public function getEnd(): ?\DateTime
public function getEnd(): ?DateTime
{
$this->localizeDates();
@@ -225,10 +227,10 @@ class Timesheet implements EntityWithMetaFields
}
/**
* @param \DateTime $end
* @param DateTime $end
* @return Timesheet
*/
public function setEnd(?\DateTime $end): Timesheet
public function setEnd(?DateTime $end): Timesheet
{
$this->end = $end;
@@ -422,10 +424,10 @@ class Timesheet implements EntityWithMetaFields
}
/**
* BE WARNED: this method should NOT be used programmatically, there is very likely no reason for it!
* BE WARNED: this method should NOT be used.
* It was ONLY introduced for the command "kimai:import-v1".
*
* @internal
* @deprecated since it was introduced, only meant for the initial migration. Will be removed with 1.0.
* @param string $timezone
* @return Timesheet
*/