Completed
Pull Request — 5.6 (#2830)
by Jeroen
14:14
created

TranslatorBundle/Service/Command/DiffCommand.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\TranslatorBundle\Service\Command;
4
5
use Doctrine\DBAL\Migrations\Configuration\Configuration;
6
use Doctrine\DBAL\Migrations\Tools\Console\Command\GenerateCommand;
7
use Symfony\Component\Console\Input\InputInterface;
8
use Symfony\Component\Console\Output\OutputInterface;
9
10
/**
11
 * Class DiffCommand.
12
 *
13
 * @deprecated This class is deprecated since KunstmaanTranslatorBundle 5.2 and will be removed in 6.0.
14
 */
15
class DiffCommand extends GenerateCommand
16
{
17
    protected function configure()
18
    {
19
        parent::configure();
20
    }
21
22
    public function execute(InputInterface $input, OutputInterface $output)
23
    {
24
        $configuration = $this->getMigrationConfiguration($input, $output);
25
        $sql = $this->getApplication()->getKernel()->getContainer()->get('kunstmaan_translator.service.migrations.migrations')->getDiffSqlArray();
0 ignored issues
show
It seems like you code against a specific sub-type and not the parent class Symfony\Component\Console\Application as the method getKernel() does only exist in the following sub-classes of Symfony\Component\Console\Application: Symfony\Bundle\FrameworkBundle\Console\Application. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
26
27
        $up = $this->buildCodeFromSql($configuration, $sql);
28
        $down = '';
29
30
        if (!$up && !$down) {
31
            $output->writeln('No changes detected in your mapping information.', 'ERROR');
32
33
            return 0;
34
        }
35
36
        $version = date('YmdHis');
37
        $path = $this->generateMigration($configuration, $input, $version, $up, $down);
38
39
        $output->writeln(sprintf('Generated new migration class to "<info>%s</info>" from schema differences.', $path));
40
41
        return 0;
42
    }
43
44
    private function buildCodeFromSql(Configuration $configuration, array $sql)
45
    {
46
        $currentPlatform = $configuration->getConnection()->getDatabasePlatform()->getName();
47
        $code = [
48
            "\$this->abortIf(\$this->connection->getDatabasePlatform()->getName() != \"$currentPlatform\", \"Migration can only be executed safely on '$currentPlatform'.\");", '',
49
        ];
50
        foreach ($sql as $query) {
51
            if (strpos($query, $configuration->getMigrationsTableName()) !== false) {
52
                continue;
53
            }
54
            $code[] = "\$this->addSql(\"$query\");";
55
        }
56
57
        return implode("\n", $code);
58
    }
59
}
60